一、組件執行的生命周期: 參考 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函數重新執行。