React組件的生命周期詳細描述
一、什么是生命周期
組件的生命周期就是React的工作過程,就好比人有生老病死,自然界有日月更替,每個組件在網(wǎng)頁中也會有被創(chuàng)建、更新和刪除,如同有生命的機體一樣。
React組件的生命周期可以分為三個過程
- 裝載(掛載)過程(mount):就是組件第一次在DOM樹中渲染的過程。
- 更新過程(update):組件被重新渲染的過程。
- 卸載過程(unmount):組件從DOM中被移除的過程。
二、裝載過程
依次調(diào)用如下函數(shù)constructor、getInitialState、getDefaultProps、componentWillMount、render、componentDidMount。
1、constructor
就是ES6里的構造函數(shù),創(chuàng)建一個組件類的實例,在這一過程中要進行兩步操作:初始化state,綁定成員函數(shù)的this環(huán)境。
2、render
render是React組件中最為重要的一個函數(shù)。這是react中唯一不可忽略的函數(shù),在render函數(shù)中,只能有一個父元素。render函數(shù)是一個純函數(shù),它并不進行實際上的渲染動作,它只是一個JSX描述的結(jié)構,最終是由React來進行渲染過程,render函數(shù)中不應該有任何操作,對頁面的描述完全取決于this.state和this.props的返回結(jié)果,不能在render調(diào)用this.setState。
- 有一個公式總結(jié)的非常形象 UI=render(data)
3、componentWillMount和componentDidMount
這兩個函數(shù)分別在render前后執(zhí)行,由于這一過程通常只能在瀏覽器端調(diào)用,所以我們在這里獲取異步數(shù)據(jù),而且在componentDidMount調(diào)用的時候,組件已經(jīng)被裝載到DOM樹上了。
三、更新過程
簡單來說就是props和state被修改的過程,依次調(diào)用componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate。
1、componentWillReceiveProps(nextProps)
并不是只有在props發(fā)生改變的時候才會被調(diào)用,實際上只要是父組件的render函數(shù)被調(diào)用,render里面被渲染的子組件就會被更新,不管父組件傳給子組件的props有沒有被改變,都會觸發(fā)子組件的componentWillReceiveProps過程,但是,this.setState方法的觸發(fā)過程不會調(diào)用這個函數(shù),因為這個函數(shù)適合根據(jù)新的props的值來計算出是不是要更新內(nèi)部狀態(tài)的state。
2、shouldComponentUpdate(nextProps, nextState)
這個函數(shù)的重要性,僅次于render,render函數(shù)決定了該渲染什么,而shouldComponentUpdate決定了不需要渲染什么,都需要返回函數(shù),這一過程可以提高性能,忽略掉沒有必要重新渲染的過程。
3、componentWillUpdate和componentDidUpdate
和裝載過程不同,這里的componentDidUpdate,既可以在瀏覽器端執(zhí)行,也可以在服務器端執(zhí)行
4、觸發(fā)render
在react中,觸發(fā)render的有4條路徑。
以下假設shouldComponentUpdate都是按照默認返回true的方式:
(1) 首次渲染Initial Render。
(2) 調(diào)用this.setState (并不是一次setState會觸發(fā)一次render,React可能會合并操作,再一次性進行render)。
(3) 父組件發(fā)生更新(一般就是props發(fā)生改變,但是就算props沒有改變或者父子組件之間沒有數(shù)據(jù)交換也會觸發(fā)render)。
(4) 調(diào)用this.forceUpdate。

注意:如果在shouldComponentUpdate里面返回false可以提前退出更新路徑。
四、卸載過程
實際中很少用到,這里只有一個componentWillUnmount,一般在componentDidMount里面注冊的事件需要在這里刪除。
五、生命周期流程
1、第一次初始化渲染顯示: ReactDOM.render()
constructor():創(chuàng)建對象初始化 statecomponentWillMount() :將要插入回調(diào)render() :用于插入虛擬 DOM 回調(diào)componentDidMount() :已經(jīng)插入回調(diào)
2、每次更新 state: this.setState()
componentWillUpdate(): 將要更新回調(diào)render(): 更新(重新渲染)componentDidUpdate(): 已經(jīng)更新回調(diào)
3、移除組件: ReactDOM.unmountComponentAtNode(containerDom)
- componentWillUnmount() : 組件將要被移除回調(diào)
六、示例
<div id='container'></div>
<script type="text/babel">
class LifeCycle extends React.Component {
constructor(props) {
super(props);
alert("Initial render");
alert("constructor");
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");
}
setTheState() {
let s = "hello";
if (this.state.str === s) {
s = "HELLO";
}
this.setState({
str: s
});
}
forceItUpdate() {
this.forceUpdate();
}
render() {
alert("render");
return(
<div>
<span>{"Props:"}<h2>{parseInt(this.props.num)}</h2></span>
<br />
<span>{"State:"}<h2>{this.state.str}</h2></span>
</div>
);
}
}
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
num: Math.random() * 100
};
}
propsChange() {
this.setState({
num: Math.random() * 100
});
}
setLifeCycleState() {
this.refs.rLifeCycle.setTheState();
}
forceLifeCycleUpdate() {
this.refs.rLifeCycle.forceItUpdate();
}
unmountLifeCycle() {
// 這里卸載父組件也會導致卸載子組件
ReactDOM.unmountComponentAtNode(document.getElementById("container"));
}
parentForceUpdate() {
this.forceUpdate();
}
render() {
return (
<div>
<a href="javascript:;" onClick={this.propsChange.bind(this)}>propsChange</a>
<a href="javascript:;" onClick={this.setLifeCycleState.bind(this)}>setState</a>
<a href="javascript:;" onClick={this.forceLifeCycleUpdate.bind(this)}>forceUpdate</a>
<a href="javascript:;" onClick={this.unmountLifeCycle.bind(this)}>unmount</a>
<a href="javascript:;" onClick={this.parentForceUpdate.bind(this)}>parentForceUpdateWithoutChange</a>
<LifeCycle ref="rLifeCycle" num={this.state.num}></LifeCycle>
</div>
);
}
}
ReactDOM.render(
<Container></Container>,
document.getElementById('container')
);
</script>
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!
相關文章
React組件實例三大屬性state props refs使用詳解
這篇文章主要為大家介紹了React組件實例三大屬性state props refs使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
React中獲取數(shù)據(jù)的3種方法及優(yōu)缺點
這篇文章主要介紹了React中獲取數(shù)據(jù)的3種方法及優(yōu)缺點,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02

