react教程 — 组件的生命周期 和 执行顺序
一、组件执行的生命周期: 参考 https://www.cnblogs.com/soyxiaobi/p/9559117.html 或 https://www.cnblogs.com/kdcg/p/9182393.html(含生命周期函数 传进来的参数)
1、初始没有改变state、props 的生命周期:
constructor、componentWillMount、render 、【子组件对应这4个周期函数】、componentDidMount 依次执行
2、改变 state 后的生命周期:
a、父组件的 state 改变:
shouldComponentUpdate、componentWillUpdate、render、【子组件的 componentWillReceiveProps、子组件对应父组件这4个周期函数】、componentDidUpdate
父组件的的state改变,会引起子组件 state 相关的生命周期函数运行。
b、子组件的 state 改变:
shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate
子组件的state改变,不会引起父组件的变化。
3、改变 props 后的 生命周期:【props改变,不会引起父子组件的任何变化,state变化才引起子组件的变化】
父组件传递给子组件的props改变,不会引起任何变化。只有父组件state改变,父组件render函数运行,所有子组件递归更新。
所以父组件传递给子组件的props值,一般使用state的值,不然给子组件的props值改变了,但是没有办法传递到子组件中,得等触发了父组件的render函数,才能把数据传递给子组件。
父组件的 state 设置,都会触发子组件的 componentWillReceiveProps 生命周期函数,且把函数参数是props值。
代码演示:
父组件
import React from 'react' import Two from './component/two' class DataFlow extends React.Component{ constructor(props){ super(props) console.log('constructor'); } state = { name: 'ydfd' } componentWillMount(){ // 渲染前的时刻,即 render前执行 console.log('componentWillMount'); } componentDidMount(){ // 渲染后的时刻,即 render后执行 console.log('componentDidMount') } componentWillReceiveProps (){ console.log('componentWillReceiveProps') } componentWillUnmount(){ // 组件的卸载 console.log('componentWillUnmount') } // 组件自身的 state 更新了,那么会依次执行 shouldComponentUpdate 、 componentWillUpdate 、render 和 componentDidUpdate 。 shouldComponentUpdate(){ // 是一个特别的方法,当方法返回 false 的时候,组件不再向下执行生命周期方法。 console.log('shouldComponentUpdate') return true } componentWillUpdate(){ // 更新过程中渲染前的时刻,不能在这里执行 setState console.log('componentWillUpdate'); } componentDidUpdate(){ // 更新过程中渲染后的时刻 console.log('componentDidUpdate'); } click(){ this.setState({ name: 'yuu' }) } render(){ console.log('顶级组件 render 方法') return ( <div className="fatherBox"> <h1>顶层组件</h1> <p>{this.state.name}</p> <button onClick={this.click.bind(this)}>触发事件</button> <Two name={this.state.name}></Two> </div> ) } } export default DataFlow;
子组件
import React from 'react' class Two extends React.Component{ constructor(props){ super(props) console.log('child === constructor'); } componentWillMount(){ // 渲染前的时刻,即 render前执行 console.log('child === componentWillMount'); } componentDidMount(){ // 渲染后的时刻,即 render后执行 console.log('child === componentDidMount') } componentWillReceiveProps (newProps){ console.log('child === componentWillReceiveProps',newProps) } componentWillUnmount(){ // 组件的卸载 console.log('child === componentWillUnmount') } // 组件自身的 state 更新了,那么会依次执行 shouldComponentUpdate 、 componentWillUpdate 、render 和 componentDidUpdate 。 shouldComponentUpdate(){ // 是一个特别的方法,当方法返回 false 的时候,组件不再向下执行生命周期方法。 console.log('child === shouldComponentUpdate') return true } componentWillUpdate(){ // 更新过程中渲染前的时刻,不能在这里执行 setState console.log('child === componentWillUpdate'); } componentDidUpdate(){ // 更新过程中渲染后的时刻 console.log('child === componentDidUpdate'); } render(){ console.log('二级组件 render 方法') return ( <div className="twoBox"> <h2>二级组件</h2> <p>{this.props.name}</p> </div> ) } } export default Two;
二、生命周期 图示: https://www.jianshu.com/p/514fe21b9914
a、组件初始化阶段:
constructor
b、组件的挂载(Mounting)阶段:
componentWillMount:【新版已经改名】
render:
componentDidMount:组件挂载到DOM后调用,且只会被调用一次
c、组件的更新(update)阶段:
a、
三、各生命周期 中 设置 调用 setState设置 state 的结果:https://www.jianshu.com/p/e09cbecca1d1
1、constructor:这里不会使用 setState 设置state 值,直接初始化。
2、componentWillMount: 只是把state合并到初始化状态中,而根本不会触发render ;在这里更新state,就等同于直接写在this.state中,所以,在此生命周期中的setState根本没有意义;
3、shouldComponentUpdate: 禁止使用。
4、componentWillUpdate: 禁止使用
5、render :render 中不能 setState 设置state,不然就会报错。 render 是 props、state 的纯函数。
6、componentDidMount:正常使用。 初始化时传递给子组件的数据,不要在 这里设置。不然,初始化时,有效数据并没有子组件,而是更新时传递过去。
总结:
生命周期中setState的使用情况:
无意义使用:componentWillMount,componentWillUnmount;
有条件使用:componentDidUpdate;
禁止使用:componentWillUpdate,shouldComponentUpdate;
正常使用:componentWIllReceiveProps,componentDidMount。
生命周期中setState是否触发更新:
componentWillMount和componentWillReceiveProps中,setState会被react内部处理,而不触发render;
其他生命周期均正常出发更新渲染。
上面讲的是class组件的执行过程,函数组件是没有生命周期的。但是函数组件 的 父组件,render执行,子组件都会重新渲染的,即子组件的组件函数重新执行。
将上面的子组件改成 函数组件
import React from 'react'; function Test(){ console.log('函数组件内'); return ( <div id="home-container"> <button onClick={testClick}> 子组件按钮 </button> </div> ) } export default Test;
父组件的state改变,会引起子组件的Test函数重新执行。