React入门--------组件的生命周期

时间:2023-03-08 17:19:16
  • Mounting/组件挂载相关:

componentWillMount

componentDidMount

  • Updating/组件更新相关:

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

componentDidUpdate

  • Unmounting/组件移除相关:

componentWillUnmount

一、Mounting/组件挂载相关

componentWillMount

在组件挂载之前执行,但仅执行一次,即使多次重复渲染改组件,或者改变了组件的state。若希望该回到能执行多次,可以使用ReactDOM.unmountComponentAtNode移除掉已有的组件,然后再重新render。

    var diva = document.getElementById('a');
var divb = document.getElementById('b');
var i=;
var Component1 = React.createClass({
componentWillMount:function(){
console.log(++i)
},
render: function() {
console.log(Date.now());
return <div name={this.props.name}>我只是一个安静的div</div>
}
});

  //触发componentWillMount,render
ReactDOM.render(
<Component1 />, diva
);
  
  //未触发componentWillMount,触发render
ReactDOM.render(
<Component1 />, diva
);

  //触发componentWillMount,render
ReactDOM.render(
<Component1 />, divb
);
  //未触发componentWillMount,未触发render
ReactDOM.render(
<Component1 />, divb
);

componentDidMount

在组件挂载之后执行,同componentWillMount一样,同一个组件重复渲染只执行一次,卸载组件后重新渲染可以重新触发一次。

二、Updating/组件更新相关

componentWillReceiveProps

在组件接收到props的时间点之前调用,注意组件初始化渲染时不会调用。

    var i = 0;
var div = document.getElementById('a'),
var div2 = document.getElementById('b'); var Component1 = React.createClass({
componentWillReceiveProps: function(){
console.log(i++)
},
clickCb: function() {
React.render(
<Component1 />, div2
);
},
render: function() {
return <div onClick={this.clickCb}>点我给下一个div挂载组件</div>
}
}); React.render(
<Component1 />, div //初始化不会触发componentWillReceiveProps
);
React.render(
<Component1 />, div //重复渲染会触发componentWillReceiveProps
);
React.unmountComponentAtNode(div); //移除掉已有组件
React.render(
<Component1 />, div //初始化不会触发componentWillReceiveProps
);

运行结果如下:

React入门--------组件的生命周期

该接口带有一个参数nextProps,可以利用它来获取新的props的值(this.props获取到的是当前的,也就是旧的props)

  var i = 0;
var div = document.getElementById('a');
var render = function(){
React.render(
<Component1 i={i++} />, div
);
}; var Component1 = React.createClass({
componentWillReceiveProps: function(nextProps){
console.log(this.props.i, nextProps.i)
},
render: function() {
return <div onClick={render}>props.i的值是:{this.props.i}</div>
}
});
render();

运行结果如下

React入门--------组件的生命周期

shouldComponentUpdate

该接口实际是在组件接收到了新的props或者新的state的时候会立即调用,然后通过返回值来决定是否要重新渲染当前的组件。

接口带两个参数,第一个参数表示新的props,第二个参数表示新的state。

  var div = document.getElementById('a');

  var Component1 = React.createClass({
getInitialState: function(){
return { i : }
},
shouldComponentUpdate: function(nextProps, nextState){
console.log( this.state.i, nextState.i );
return nextState.i > ? true : false; //返回true才会渲染组件
},
clickCb: function(){
this.setState({
i : this.state.i +
})
},
render: function() {
return <div onClick={this.clickCb}>state.i的值是:{this.state.i}</div>
}
});
ReactDOM.render(
<Component1 />, div
);

点击第四次之后才会渲染组件,在div里显示正确的新state.i

React入门--------组件的生命周期

componentWillUpdate

同shouldComponentUpdate一样,在组件收到新的props或者state的时候会调用,而且也有着两个参数来获取新的props和state。

不过本接口仅在shouldComponentUpdate执行并返回了true的时候才会被调用。

在上一个代码实例中做点改动

 componentWillUpdate: function(nextProps, nextState){
console.log( 'yoyoyo', this.state.i, nextState.i );
},

React入门--------组件的生命周期

componentDidUpdate

在组件更新,重新渲染完毕之后调用,它和componentWillUpdate一样有着两个参数来获取新的props和state

 var div = document.getElementById('a');

    var Component1 = React.createClass({
getInitialState: function(){
return { i : }
},
shouldComponentUpdate: function(nextProps, nextState){
console.log( this.state.i, nextState.i );
return nextState.i > ? true : false; //返回true才会执行componentWillUpdate并重新渲染组件
},
componentDidUpdate: function(nextProps, nextState){
console.log( '已经渲染完毕咯', this.state.i, nextState.i );
},
componentWillUpdate: function(nextProps, nextState){
console.log( '还没渲染哦', this.state.i, nextState.i );
},
clickCb: function(){
this.setState({
i : this.state.i +
})
},
render: function() {
return <div onClick={this.clickCb}>state.i的值是:{this.state.i}</div>
}
});
ReactDOM.render(
<Component1 />, div
);

运行结果如下:

React入门--------组件的生命周期

三、Unmounting/组件移除相关:

 var div = document.getElementById('a');
var div2 = document.getElementById('b'); var Component1 = React.createClass({
    DOMArr : [],
    getInitialState: function(){
      return { i : }
    },
    componentDidUpdate: function(nextProps, nextState){
      var dom = document.createElement('p');
      dom.innerText = this.state.i;
      div2.appendChild(dom);
      this.DOMArr.push(dom);
},
    componentWillUnmount: function(){
      if(!this.DOMArr.length) return;
      var i = ;
      while(i < this.DOMArr.length){console.log(i);
        div2.removeChild(this.DOMArr[i++]); //移除componentDidUpdate里添加过的DOM
      }
    },
    clickCb: function(){
      this.setState({
        i : this.state.i +
      })
    },
    render: function() {
      return <div onClick={this.clickCb}>state.i的值是:{this.state.i}</div>
    }
});
ReactDOM.render(
  <Component1 />, div
); div2.addEventListener('click',function(){
  ReactDOM.unmountComponentAtNode(div) //点击div2则卸载掉第一个div里的组件
}, false)

运行结果如下:

React入门--------组件的生命周期

四、getDefaultProps和getInitialState

getDefaultProps

该方法是所有我们提及的方法中最先触发的,可以在该方法里return 一个对象来作为组件默认的props值(如果父组件传进来了props,以父组件为主),它只在组件初次挂载到页面上时触发,即使你重新挂载了组件。

getInitialState

用于给组件初始化state的值,调用该方法要求必须return 一个对象或者null,否则报错。该方法在组件每次实例化的时候都会触发。

var diva = document.getElementsByTagName('div')[],
divb = document.getElementsByTagName('div')[];
var Component1 = React.createClass({
getDefaultProps: function(){
console.log('getDefaultProps');
return { name : Date.now() }
},
getInitialState: function(){
console.log('getInitialState');
return null; //必须返回一个null或对象,否则会报错
}, render: function() {
console.log(Date.now());
return <div name={this.props.name}>我只是一个安静的div</div>
}
});
ReactDOM.render(
{/* 触发一次 getDefaultProps 和 getInitialState */}
<Component1 />, diva
);
ReactDOM.render(
{/* getDefaultProps 和 getInitialState都不触发 */}
<Component1 />, diva
);
ReactDOM.unmountComponentAtNode(diva);
ReactDOM.render(
{/* 触发一次getInitialState */}
<Component1 name="a"/>, diva
);
ReactDOM.render(
{/* 触发一次getInitialState */}
<Component1/>, divb
);

五、总结

上面是9个周期接口,它们被触发的顺序?

 var Component1 = React.createClass({
getDefaultProps: function(){
console.log('getDefaultProps')
},
getInitialState: function(){
console.log('getInitialState');
return null
},
componentWillMount: function(){
console.log('componentWillMount')
},
componentDidMount: function(){
console.log('componentDidMount')
},
componentWillReceiveProps: function(){
console.log('componentWillReceiveProps')
},
shouldComponentUpdate: function(){
console.log('shouldComponentUpdate');
return true;
},
componentWillUpdate: function(){
console.log('componentWillUpdate')
},
componentDidUpdate: function(){
console.log('componentDidUpdate')
},
componentWillUnmount: function(){
console.log('componentWillUnmount')
},
render: function() {
return <div>我只是一个安静的div</div>
}
});
ReactDOM.render(
<Component1 />, document.body
);
ReactDOM.render(
<Component1 />, document.body
);
ReactDOM.unmountComponentAtNode(document.body)

结果如下:

React入门--------组件的生命周期