zoukankan      html  css  js  c++  java
  • 浅谈React和VDom关系

    组件化

    1. 组件的封装
    2. 组件的复用

    组件的封装

    • 视图
    • 数据
    • 视图和数据之间的变化逻辑
    import React, {Component} from 'react';
    
    export  default class List extends Component{
        constructor(props){
            super(props);
            this.state = { //数据
                list:this.props.data,
            }
        }
        render() { 
            return (
                <div> 
                    <ul>
                        {this.state.list.map(function(item,index){
                            return (<li key={index}>{item}</li>);
                        })}
                    </ul>
                </div>
            )
        }
    }

    组件的复用(通过props传递)

    import React, {Component} from 'react';
    import List from './list'; //组件
    import Title from './title';//组件
    export  default class Todo extends Component{
        constructor(props){
            super(props);
            this.state = {
                list:['Foo','Bar'],
            }
        }
        todoList (item){
            this.state.list.push(item);
            const newList=this.state.list;
            this.setState({
                list:newList,
            })
        }
        render() {
            return (
               <div>
                   <Title todoList={this.todoList.bind(this)} /> 
                   <List data={this.state.list}/>
                   <Title todoList={this.todoList.bind(this)} /> //复用
                   <List data={[1,2,3]}/> //复用
               </div>
            )
        }
    }
    

    JSX

    React引入JSX,并将它作为了一个独立的标准开放,React.createElement也是可以自定义去修改的,

    jsx语法(语法糖)需要转成js

    ReactElement createElement(  // 参数——标签属性子元素
      string/ReactClass type,  
      [object props],  
      [children ...]  
    )  
    

      

    npm i babel-cli -g

    npm i --save-dev babel-plugin-transform-react-jsx

    新建.babelrc文件,添加

    {
      "plugins": ["transform-react-jsx"]
    }

    在项目根目录中运行babel --plugins transform-react-jsx src/components/todo/index.js

    经过编译:转化成React.createElement,类似于vitual dom 的 h 函数 

    import React, { Component } from 'react';
    import List from './list'; //组件
    import Title from './title'; //组件
    export default class Todo extends Component {
        constructor(props) {
            super(props);
            this.state = {
                list: ['Foo', 'Bar']
            };
        }
        todoList(item) {
            this.state.list.push(item);
            const newList = this.state.list;
            this.setState({
                list: newList
            });
        }
        render() {
            return React.createElement(
                'div', //直接渲染
                null,
                React.createElement(Title, { todoList: this.todoList.bind(this) }), //转化成React.createElement
                React.createElement(List, { data: this.state.list }), //List 是自定义构造函数,List 组件必须有render
                React.createElement(Title, { todoList: this.todoList.bind(this) }),
                React.createElement(List, { data: this.state.list })
            );
        }
    }
    
    
    
    React.createElement(List, { data: this.state.list }), //List 是自定义构造函数,List 组件必须有render
    相当于var list = new List({data: this.state.list});
    var vNode = list.render(); //通过层层的render函数,最终React.createElement html标签

      

    在文件开始添加 /* @jsx h */ 改变 React.createElement

    /* @jsx h */
    import React, { Component } from 'react';
    import List from './list'; //组件
    import Title from './title'; //组件
    export default class Todo extends Component {
        constructor(props) {
            super(props);
            this.state = {
                list: ['Foo', 'Bar']
            };
        }
        todoList(item) {
            this.state.list.push(item);
            const newList = this.state.list;
            this.setState({
                list: newList
            });
        }
        render() {
            return h(
                'div',
                null,
                h(Title, { todoList: this.todoList.bind(this) }),
                h(List, { data: this.state.list }),
                h(Title, { todoList: this.todoList.bind(this) }),
                h(List, { data: this.state.list })
            );
        }
    }
    

      

    JSX中的VDom体现

    jsx就是模版,最终需要转化成html,初次渲染,修改state后的setState 的re-render,正好适用于vDOM  

    ReactDOM.render(<App />, document.getElementById('root')); //初次渲染 <App /> JSX对象
    //通过vDom的patch(container,vnode),而对于re-render是通过setState
    todoList (item){
        this.state.list.push(item);
        const newList=this.state.list;
        this.setState({ //re-render patch(vnode,newVnode)
            list:newList,
        })
    }
    

      

    源码下载  

    该随笔相关代码已上传到github,地址:https://github.com/10086XIAOZHANG/ReactVisualDomDemo  

        

  • 相关阅读:
    BZOJ2219数论之神——BSGS+中国剩余定理+原根与指标+欧拉定理+exgcd
    Luogu 3690 Link Cut Tree
    CF1009F Dominant Indices
    CF600E Lomsat gelral
    bzoj 4303 数列
    CF1114F Please, another Queries on Array?
    CF1114B Yet Another Array Partitioning Task
    bzoj 1858 序列操作
    bzoj 4852 炸弹攻击
    bzoj 3564 信号增幅仪
  • 原文地址:https://www.cnblogs.com/fuGuy/p/9226248.html
Copyright © 2011-2022 走看看