剛開始學習react時總是搞不清楚相關函數的調用順序,導致寫出的代碼可能存在不可預期的現象。後來寫了一段驗證代碼,確定了調用順序如下
- start
componentWillMount
render
componentDidMount
componentWillUpdate
render
componentDidUpdate
- setState
componentWillUpdate
render
componentDidUpdate
- changePropsInParentComponent
componentWillReceiveProps
componentWillUpdate
render
componentDidUpdate
驗證代碼如下
子組件MyChild代碼
import React from 'react';
const lifeCircle = ['start'];
let hOutputTimer = null;
function addLog(msg) {
lifeCircle.push(msg);
if (hOutputTimer) {
clearTimeout(hOutputTimer);
}
hOutputTimer = setTimeout(() => {
console.log(lifeCircle.join('\r\n'));
lifeCircle.length = 0;
hOutputTimer = null;
}, 10000)
}
export {addLog}
// implement of the CLASS
export default class MyChild extends React.Component {
constructor(props) {
super(props);
this.state = {
sss: '111'
}
}
componentDidMount () {
addLog('componentDidMount')
}
componentWillMount () {
addLog('componentWillMount')
}
componentWillReceiveProps () {
addLog('componentWillReceiveProps')
this.setState({sss: 'cccc'}) // 這個setState不影響各函數的調用順序
}
componentWillUpdate () {
addLog('componentWillUpdate')
}
componentDidUpdate () {
addLog('componentDidUpdate')
}
render() {
addLog('render')
return (
<div>
<button onClick={() => {
addLog('setStateInSelfComponent');
this.setState({sss:'222'})
}}>sss</button>
<div>{this.props.ppp}</div>
<div>{this.state.sss}</div>
</div>
)
}
}
父組件ParentComp代碼
import React from 'react';
import MyChild from './mychild';
class ParentComp extends React.Component {
state = {
ppp: 'p111'
}
render () {
return (
<div>
<button onClick={() => {
addLog('- changePropsInParentComponent');
this.setState({ppp:'p222'});
}}>ppp</button>
<MyChild ppp={this.state.ppp} />
</div>
);
}
}
export default ParentComp