首页 > 代码库 > react初始化阶段

react初始化阶段

  1. 初始化阶段可以使用的函数:
    getDefaultProps:只调用一次,实例之间共享引用。只有在组件的第一个实例被初始化的时候,才会调用他,然后react会把这个函数的返回结果保存起来,从第二个实例开始,他们的默认属性都是这同一个结果。实例之间共享引用,在js中有两种类型的数据,一种值类型,比如字符串,布尔值等,一种是引用类型,比如数组,对象等,如果函数返回的是引用类型的数据,那么react会把引用保存起来,在创建不同的实例的时候,他会使用同一个引用当做属性,但是我们知道,引用指向的都是同一个地址,所以说不同实例之间操作的其实是同一个数据,所以在用这个函数的时候,要注意返回的是引用还是值。

    getInitialState:初始化每个实例特有的状态。从这个函数开始,每个实例被初始化的时候,都会调用他, 不像第一个函数只会调用一次,第一个函数处理的是属性,第二个函数处理的是状态,由于状态是每个实例自己内部的信息,每个实例要维护自己状态,所以不同的实例有不同的状态,那么都需要调用这个函数。

    componentWillMount:render之前最后一次修改状态的机会。在这个时候,你还是可以修改状态的,但是在render里面就不可以在修改状态了。

    render:只能访问this.props和this.state,只有一个顶层组件,不允许修改状态和dom输出。this.props和this.state是render特有的两个数据源,除此以外,你不应该在获取其他的数据信息。只有一个顶层组件?render的返回值只能是一个组件,这个组件可以包含很多的子组件,也可以包含很多的子代码,但是本质上他还是一个组件,你不能返回一个数组。不允许修改状态和dom输出。如果一定要修改,也是可以的,但是react不推荐这么做,如果你修改了状态和输出的话,那么render函数就无法再服务端进行使用,当然我们大部分时候是在客户端使用的render函数,如果你想提高网站的加载性能,就可以在服务端进行处理,但是你的render函数需要修改状态和dom输出,在服务端得时候是没有这样的环境的,所以你如果修改了状态和输出,就只能在浏览器使用了,这回大大的限制你的系统性能。第二个原因就是你如果在render里面修改了状态和输出,会导致代码的逻辑变得非常的复杂,很难经过状态分析出结果,react设计目的之一就是让组件的逻辑变得清晰简单,这样就违背了这样的目的。你自己还是别人就很难看懂这段代码。

    componentDidMount:成功render并渲染完成真实dom之后触发,可以修改dom。这个函数被调用的时候,dom已经被创建。


  2. 实例:查看触发顺序。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.min.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            var style={
               color:"red",
               border:"1px solid #f99",
               width:"200px",
               height:"50px"
            };
            var HelloWorld=React.createClass({
               getDefaultProps: function(){
               console.log("getDefaultProps,1")
               },
               getInitialState: function(){
                  console.log("getInitialState,2");
                  return null;
               },
               componentWillMount: function(){
                  console.log("componentWillMount,3")
               },
               render: function(){
                   console.log("render,4")
                   return <p ref="childp">hello,{(
                      function(obj){
                      if(obj.props.name)
                        return obj.props.name
                       else
                        return "world"
                      }
                   )(this)}</p>
               },
               componentDidMount:function(){
                   console.log("componentDidMount,5");
               },
            });
            React.render(<div style={style}>HelloWorld</div>,document.body)
        </script>
    </body>
    </html>

    注意上面代码中红色的标记部分,我们只是输出的字符串HelloWorld,并不是标签<HelloWorld></Helloworld>,所以此时的控制台和输出是这样。

    技术分享

    我们可以看出,getDefaultProps在实际的使用中,是直接调用的,也就是在React.createClass之后,就会被调用并把结果存储起来,及时你没有生成实例,这个函数也会被调用,react这么做主要目的就是为了提高性能,尽可能早的将我们要做的事情处理好,这样当我们要使用HelloWorld实例的时候,就会省掉调用这个函数的时间从而提高性能。我们改一下代码,让其正确输出。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.min.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            var style={
               color:"red",
               border:"1px solid #f99",
               width:"200px",
               height:"50px"
            };
            var HelloWorld=React.createClass({
               getDefaultProps: function(){
               console.log("getDefaultProps,1")
               },
               getInitialState: function(){
                  console.log("getInitialState,2");
                  return null;
               },
               componentWillMount: function(){
                  console.log("componentWillMount,3")
               },
               render: function(){
                   console.log("render,4")
                   return <p ref="childp">hello,{(
                      function(obj){
                      if(obj.props.name)
                        return obj.props.name
                       else
                        return "world"
                      }
                   )(this)}</p>
               },
               componentDidMount:function(){
                   console.log("componentDidMount,5");
               },
            });
            React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body)
        </script>
    </body>
    </html>



    技术分享

  3. 各个实例的正确用法
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/jquery/2.0.3/jquery.min.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.min.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
           $(document).ready(
              function(){
                 var count=0;
                 var style={
                    color:"red",
                    border:"1px solid #090",
                 };
                 var HelloWorld=React.createClass({
                    getDefaultProps:function(){
                        console.log("getDefaultProps,1");
                        return{name:"Tom"};
                    },
                    getInitialState:function(){
                        console.log("getInitialState,2");
                        return{
                        myCount:count++,
                        ready:false
                        };
                    },
                    componentWillMount:function(){
                        console.log("componentWillMount,3");
                        this.setState({ready:true});
                    },
                    render:function(){
                         console.log("render,4");
                         return <p ref="childp">Hello,{
                             this.props.name ? this.props.name : "World"
                         }<br/>{""+this.state.ready}</p>;
                    },
                    componentDidMount:function(){
                         console.log("componentDidMount,5");
                         //这里才可以操作dom
                         $(React.findDOMNode(this)).append("surprise!");
                    },
                    //HelloWolrld内部
                 });
                 React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body)    
                 //function 内部         
              }
              //ready内部
           )
        </script>
    </body>
    </html>



  4. 输出count,生成多个HelloWorld
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/jquery/2.0.3/jquery.min.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.min.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
           $(document).ready(
              function(){
                 var count=0;
                 var style={
                    color:"red",
                    border:"1px solid #090",
                 };
                 var HelloWorld=React.createClass({
                    getDefaultProps:function(){
                        console.log("getDefaultProps,1");
                        return{name:"Tom"};
                    },
                    getInitialState:function(){
                        console.log("getInitialState,2");
                        return{
                        myCount:count++,
                        ready:false
                        };
                    },
                    componentWillMount:function(){
                        console.log("componentWillMount,3");
                        this.setState({ready:true});
                    },
                    render:function(){
                         console.log("render,4");
                         return <p ref="childp">Hello,{
                             this.props.name ? this.props.name : "World"
                         }<br/>{""+this.state.ready}{this.state.myCount}</p>;
                    },
                    componentDidMount:function(){
                         console.log("componentDidMount,5");
                         $(React.findDOMNode(this)).append("surprise!");
                    },
                    //HelloWolrld内部
                 });
                 React.render(<div style={style}><HelloWorld></HelloWorld><br/><HelloWorld></HelloWorld></div>
    
                     ,document.body)    
                 //function 内部         
              }
              //ready内部
           )
        </script>
    </body>
    </html>

    技术分享

react初始化阶段