React組件的生命周期詳細(xì)描述
一、什么是生命周期
組件的生命周期就是React的工作過(guò)程,就好比人有生老病死,自然界有日月更替,每個(gè)組件在網(wǎng)頁(yè)中也會(huì)有被創(chuàng)建、更新和刪除,如同有生命的機(jī)體一樣。
React組件的生命周期可以分為三個(gè)過(guò)程
- 裝載(掛載)過(guò)程(mount):就是組件第一次在DOM樹(shù)中渲染的過(guò)程。
- 更新過(guò)程(update):組件被重新渲染的過(guò)程。
- 卸載過(guò)程(unmount):組件從DOM中被移除的過(guò)程。
二、裝載過(guò)程
依次調(diào)用如下函數(shù)constructor、getInitialState、getDefaultProps、componentWillMount、render、componentDidMount。
1、constructor
就是ES6里的構(gòu)造函數(shù),創(chuàng)建一個(gè)組件類(lèi)的實(shí)例,在這一過(guò)程中要進(jìn)行兩步操作:初始化state,綁定成員函數(shù)的this環(huán)境。
2、render
render是React組件中最為重要的一個(gè)函數(shù)。這是react中唯一不可忽略的函數(shù),在render函數(shù)中,只能有一個(gè)父元素。render函數(shù)是一個(gè)純函數(shù),它并不進(jìn)行實(shí)際上的渲染動(dòng)作,它只是一個(gè)JSX描述的結(jié)構(gòu),最終是由React來(lái)進(jìn)行渲染過(guò)程,render函數(shù)中不應(yīng)該有任何操作,對(duì)頁(yè)面的描述完全取決于this.state和this.props的返回結(jié)果,不能在render調(diào)用this.setState。
- 有一個(gè)公式總結(jié)的非常形象 UI=render(data)
3、componentWillMount和componentDidMount
這兩個(gè)函數(shù)分別在render前后執(zhí)行,由于這一過(guò)程通常只能在瀏覽器端調(diào)用,所以我們?cè)谶@里獲取異步數(shù)據(jù),而且在componentDidMount調(diào)用的時(shí)候,組件已經(jīng)被裝載到DOM樹(shù)上了。
三、更新過(guò)程
簡(jiǎn)單來(lái)說(shuō)就是props和state被修改的過(guò)程,依次調(diào)用componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate。
1、componentWillReceiveProps(nextProps)
并不是只有在props發(fā)生改變的時(shí)候才會(huì)被調(diào)用,實(shí)際上只要是父組件的render函數(shù)被調(diào)用,render里面被渲染的子組件就會(huì)被更新,不管父組件傳給子組件的props有沒(méi)有被改變,都會(huì)觸發(fā)子組件的componentWillReceiveProps過(guò)程,但是,this.setState方法的觸發(fā)過(guò)程不會(huì)調(diào)用這個(gè)函數(shù),因?yàn)檫@個(gè)函數(shù)適合根據(jù)新的props的值來(lái)計(jì)算出是不是要更新內(nèi)部狀態(tài)的state。
2、shouldComponentUpdate(nextProps, nextState)
這個(gè)函數(shù)的重要性,僅次于render,render函數(shù)決定了該渲染什么,而shouldComponentUpdate決定了不需要渲染什么,都需要返回函數(shù),這一過(guò)程可以提高性能,忽略掉沒(méi)有必要重新渲染的過(guò)程。
3、componentWillUpdate和componentDidUpdate
和裝載過(guò)程不同,這里的componentDidUpdate,既可以在瀏覽器端執(zhí)行,也可以在服務(wù)器端執(zhí)行
4、觸發(fā)render
在react中,觸發(fā)render的有4條路徑。
以下假設(shè)shouldComponentUpdate都是按照默認(rèn)返回true的方式:
(1) 首次渲染Initial Render。
(2) 調(diào)用this.setState (并不是一次setState會(huì)觸發(fā)一次render,React可能會(huì)合并操作,再一次性進(jìn)行render)。
(3) 父組件發(fā)生更新(一般就是props發(fā)生改變,但是就算props沒(méi)有改變或者父子組件之間沒(méi)有數(shù)據(jù)交換也會(huì)觸發(fā)render)。
(4) 調(diào)用this.forceUpdate。
注意:如果在shouldComponentUpdate里面返回false可以提前退出更新路徑。
四、卸載過(guò)程
實(shí)際中很少用到,這里只有一個(gè)componentWillUnmount,一般在componentDidMount里面注冊(cè)的事件需要在這里刪除。
五、生命周期流程
1、第一次初始化渲染顯示: ReactDOM.render()
constructor():
創(chuàng)建對(duì)象初始化 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() { // 這里卸載父組件也會(huì)導(dǎo)致卸載子組件 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é)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
React不能將useMemo設(shè)置為默認(rèn)方法原因詳解
這篇文章主要為大家介紹了React不能將useMemo設(shè)置為默認(rèn)方法原因詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-07-07基于React.js實(shí)現(xiàn)原生js拖拽效果引發(fā)的思考
這篇文章主要為大家詳細(xì)介紹了基于React.js實(shí)現(xiàn)原生js拖拽效果,繼而引發(fā)的一系列思考,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03Hello?React的組件化方式之React入門(mén)小案例演示
這篇文章主要介紹了Hello?React的組件化方式-React入門(mén)小案例,本文通過(guò)Hello?React的案例,?來(lái)體驗(yàn)一下React開(kāi)發(fā)模式,?以及jsx的語(yǔ)法,需要的朋友可以參考下2022-10-10React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02詳解Jotai Immer如何實(shí)現(xiàn)undo redo功能示例詳解
這篇文章主要為大家介紹了詳解Jotai Immer如何實(shí)現(xiàn)undo redo功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04react 報(bào)錯(cuò)Module build failed: Browserslis
這篇文章主要介紹了react 報(bào)錯(cuò)Module build failed: BrowserslistError: Unknown browser query `dead`問(wèn)題的解決方法,需要的朋友可以參考下2023-06-06一看就懂的ReactJs基礎(chǔ)入門(mén)教程-精華版
現(xiàn)在最熱門(mén)的前端框架有AngularJS、React、Bootstrap等。自從接觸了ReactJS,ReactJs的虛擬DOM(Virtual DOM)和組件化的開(kāi)發(fā)深深的吸引了我,下面來(lái)跟我一起領(lǐng)略ReactJs的風(fēng)采吧~~ 文章有點(diǎn)長(zhǎng),耐心讀完,你會(huì)有很大收獲哦2021-04-04