React元件生命週期
constructor( ) 構造方法
constructor是ES6對類的預設方法,通過 new 命令生成物件例項時自動呼叫該方法。並且,該方法是類中必須有的,如果沒有顯示定義,則會預設新增空的constructor( )方法。當存在constructor的時候⚠️必須手動呼叫super方法。如果在constructor中想使用this關鍵字,就必須先呼叫super方法 MDN-super。 在constructor中如果要訪問this.props需要在super中傳入props。但是無論有沒有定義constructor,super是否傳入props引數,在react的其他生命週期中this.props都是可以使用的,這是React自動附帶的。
class MyClass extends React.component{
constructor(props){
super(props); // 宣告constructor時必須呼叫super方法
console.log(this.props); // 可以正常訪問this.props
}
}
複製程式碼
constructor 構造方法常用來初始化state
class MyClass extends React.Component {
constructor(props){
super(props);
this.state = {
list: this.props.List
};
this.state.list = []; //修改state
setTimeout(() => {
this.setState({list: [1, 2, 3]}); //非同步操作後 setState 觸發渲染
}, 100);
}
}
複製程式碼
需要注意的是,在建構函式裡定義了state,當你想在一些操作後修改state,只需要直接操作this.state
即可, 如果你在建構函式裡執行了非同步操作,就需要呼叫setState
來觸發重新渲染。在其餘的地方當你需要改變state的時候只能使用this.setState
,這樣 React 才會觸發重新整理UI渲染。
Class靜態方法例項屬性 初始化state
class ReactCounter extends React.Component {
state = {
list: []
};
}
複製程式碼
具體文章可見Class-的靜態方法
componentWillMount() 元件掛載之前
在元件掛載之前呼叫且全域性只呼叫一次。如果在這個鉤子裡可以setState,render後可以看到更新後的state,不會觸發重複渲染。該生命週期可以發起非同步請求,並setState。(React v16.3後廢棄該生命週期,可以在constructor中完成設定state)
render() 渲染元件
render是一個React元件必須定義的生命週期,用來渲染dom。⚠️不要在render裡面修改state,會觸發死迴圈導致棧溢位。render必須返回reactDom
render() {
const {nodeResultData: {res} = {}} = this.props;
if (isEmpty(res)) return noDataInfo;
const nodeResult = this.getNodeResult(res);
return (
<div className="workspace-dialog-result">
{nodeResult}
</div>
);
複製程式碼
componentDidMount() 元件掛載完成後
在元件掛載完成後呼叫,且全域性只呼叫一次。可以在這裡使用refs,獲取真實dom元素。該鉤子內也可以發起非同步請求,並在非同步請求中可以進行setState。
componentDidMount() {
axios.get('/auth/getTemplate').then(res => {
const {TemplateList = []} = res;
this.setState({TemplateList});
});
}
複製程式碼
componentWillReceiveProps (nextProps ) props即將變化之前
props發生變化以及父元件重新渲染時都會觸發該生命週期,在該鉤子內可以通過引數nextProps獲取變化後的props引數,通過this.props訪問之前的props。該生命週期內可以進行setState。(React v16.3後廢棄該生命週期,可以用新的週期 static getDerivedStateFromProps
代替)
shouldComponentUpdate(nextProps, nextState) 是否重新渲染
元件掛載之後,每次呼叫setState後都會呼叫shouldComponentUpdate判斷是否需要重新渲染元件。預設返回true,需要重新render。返回false則不觸發渲染。在比較複雜的應用裡,有一些資料的改變並不影響介面展示,可以在這裡做判斷,優化渲染效率。
componentWillUpdate(nextProps, nextState)
shouldComponentUpdate返回true或者呼叫forceUpdate之後,componentWillUpdate會被呼叫。不能在該鉤子中setState,會觸發重複迴圈。(React v16.3後廢棄該生命週期,可以用新的週期 getSnapshotBeforeUpdate
)
componentDidUpdate() 完成元件渲染
除了首次render之後呼叫componentDidMount,其它render結束之後都是呼叫componentDidUpdate。該鉤子內setState有可能會觸發重複渲染,需要自行判斷,否則會進入死迴圈。
componentDidUpdate() {
if(condition) {
this.setState({..}) // 設定state
} else {
// 不再設定state
}
}
複製程式碼
componentWillUnmount() 元件即將被解除安裝
元件被解除安裝的時候呼叫。一般在componentDidMount裡面註冊的事件需要在這裡刪除。
生命週期圖
完整的生命週期示例
class LifeCycle extends React.Component {
constructor(props) {
super(props);
this.state = {str: "hello"};
}
componentWillMount() {
alert("componentWillMount");
}
componentDidMount() {
alert("componentDidMount");
}
componentWillReceiveProps(nextProps) {
alert("componentWillReceiveProps");
}
shouldComponentUpdate() {
alert("shouldComponentUpdate");
return true; // 記得要返回true
}
componentWillUpdate() {
alert("componentWillUpdate");
}
componentDidUpdate() {
alert("componentDidUpdate");
}
componentWillUnmount() {
alert("componentWillUnmount");
}
render() {
alert("render");
return(
<div>
<span><h2>{parseInt(this.props.num)}</h2></span>
<br />
<span><h2>{this.state.str}</h2></span>
</div>
);
}
}
複製程式碼
React v16.3 新加入的生命週期 (轉載)
react v16.3刪掉以下三個生命週期
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
新增兩個生命週期
- static getDerivedStateFromProps
- getSnapshotBeforeUpdate
static getDerivedStateFromProps
- 觸發時間:在元件構建之後(虛擬dom之後,實際dom掛載之前) ,以及每次獲取新的props之後。
- 每次接收新的props之後都會返回一個物件作為新的state,返回null則說明不需要更新state.
- 配合componentDidUpdate,可以覆蓋componentWillReceiveProps的所有用法
class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
// 沒錯,這是一個static
}
}
複製程式碼
getSnapshotBeforeUpdate
- 觸發時間: update發生的時候,在render之後,在元件dom渲染之前。
- 返回一個值,作為componentDidUpdate的第三個引數。
- 配合componentDidUpdate, 可以覆蓋componentWillUpdate的所有用法。
class Example extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
// ...
}
}
複製程式碼