React生命周期浅析

引言

关于React的生命周期API,官网,有着详细说明。但在实际写代码的过程中,这些说明不能解决所有的疑惑。 所以我列举了一些编码中常见用例,供大家参考。

示例代码如下


 
/*
 use case
 1. mixin中重名生命周期方法
 2. 重复React.render同个组件
 3. 从 mount 到 unmount 再到 mount
 4. 子组件两次加载
 5. 父组件update
 6. 改变子组件的包裹
*/

var IamMixinObject = {
  componentDidMount: function(){
    console.log('mixin里的componentDidMount');
  }
};

var SonClass = React.createClass({
  mixins: [IamMixinObject],
  getDefaultProps:function(){
    console.log("getDefaultProps");
  },
  componentWillReceiveProps :function(){
    console.log("componentWillReceiveProps");
  },
  getInitialState:function(){
    console.log("getInitialState");
    return {};
  },
  componentWillMount:function(){
    console.log("componentWillMount");
  },
  componentWillUpdate:function(){
    console.log("componentWillUpdate");
  },
  shouldComponentUpdate:function(){
    console.log("shouldComponentUpdate");
    return true;
  },
  render: function(){
    console.log("render");
    return null;
  },
  componentDidUpdate: function(){
    console.log('componentDidUpdate');
  },
  componentDidMount: function(){
    console.log('componentDidMount');
  },
  componentWillUnmount: function(){
    console.log('componentWillUnmount');
  }
});


// 1. mixin中重名生命周期方法
React.render(<SonClass />, document.getElementById("forTest"));
/*
 mixin里的componentDidMount 会先于 componentDidMount输出。
 其实,mixin中和组件同名的生命周期方法,都是mixin中先执行。
*/


// 2. 重复React.render同个组件
React.render(<SonClass />, document.getElementById("forTest"));
React.render(<SonClass />, document.getElementById("forTest"));
/*
 输出:
 getDefaultProps
 getInitialState
 componentWillMount
 render
 mixin里的componentDidMount
 componentDidMount

 componentWillReceiveProps
 shouldComponentUpdate
 componentWillUpdate
 render
 componentDidUpdate 
 总结:
 第二次mount同个render组件,相当于改变 组件props。
*/

// 3. 从 mount 到 unmount 再到 mount
React.render(<SonClass />, document.getElementById("forTest"));
React.unmountComponentAtNode(document.getElementById("forTest"));
React.render(<SonClass />, document.getElementById("forTest"));
/*
 输出:
 getDefaultProps
 getInitialState
 componentWillMount
 render
 mixin里的componentDidMount
 componentDidMount
 componentWillUnmount

 getInitialState
 componentWillMount
 render
 mixin里的componentDidMount
 componentDidMount
 总结:
 unmount的时候,确实调用了componentWillUnmount方法,第二次mount的时候,并没有执行getDefaultProps方法。
 是因为,getDefaultProps Invoked once and cached when the class is created。
 它在组件类创建的时候被调用一次,其返回值会被缓存。
*/


// 4. 子组件两次装载
var FatherClass = React.createClass({
  render:function(){

    return (
      <div>
        <SonClass />
        <SonClass />      
      </div>
 )
 }
});
React.render(<FatherClass />, document.getElementById("forTest"));
/*
 输出:
 getDefaultProps
 getInitialState
 componentWillMount
 render
 getInitialState
 componentWillMount
 render

 mixin里的componentDidMount
 componentDidMount
 mixin里的componentDidMount
 componentDidMount
 总结:
 发现两次componentDidMount是后面连续触发。
 这里涉及到React的batchUpdate机制,需要另一篇文章详解。
 大概机制是,
 因为setState是异步的。
 它把变化存入一个临时队列,渲染完新的内容后才调用所有 componentDidUpdate或componentDidMount。

*/

// 5. 父组件update
var FatherClass = React.createClass({
  getInitialState:function(){
    
    return {
      changeFlag:false
    };
  },
  changeSon:function(){
    var changeFlag = this.state.changeFlag;
    this.setState({
      changeFlag: !changeFlag
    });
  },
  render:function(){
    return (
      <div onClick={this.changeSon} >
        <SonClass />                
      </div>
 )
 }
});
React.render(<FatherClass />, document.getElementById("forTest"));
/*
 输出:
 getDefaultProps
 getInitialState
 componentWillMount
 render
 mixin里的componentDidMount
 componentDidMount

 componentWillReceiveProps 
 shouldComponentUpdate
 componentWillUpdate
 render
 componentDidUpdate
 总结:
 父组件setState了,对于子组件是setProps了
*/

// 6. 改变子组件的包裹
var FatherClass = React.createClass({
  getInitialState:function(){
    
    return {
      changeFlag:false
    };
  },
  changeSon:function(){
    var changeFlag = this.state.changeFlag;
    this.setState({
      changeFlag: !changeFlag
    });
  },
  render:function(){
    var changeFlag = this.state.changeFlag; 
    var Son = changeFlag ? <SonClass /> : <div>new son<SonClass /></div>

 return (
 <div onClick={this.changeSon} >
 父组件在此 
 {
 Son
 } 
 </div>
    )
  }
});
React.render(<FatherClass />, document.getElementById("forTest"));
/*
 输出:
 getDefaultProps
 getInitialState
 componentWillMount
 render
 mixin里的componentDidMount
 componentDidMount

 componentWillUnmount

 getInitialState
 componentWillMount
 render
 mixin里的componentDidMount
 componentDidMount
 总结:
 父组件setState改变了子组件的包裹,子组件相当于重新mount

*/
                          

你可能感兴趣的:(React生命周期浅析)