# Life Cycle ###### tags: `React` `Javascript` 1. 組件從創建到死亡會經歷一些特定階段 2. React組件中包含一系列生命週期回調函數,會在特定時候調用 3. 定義組件時,會在特定的生命週期回調函數中,做特定的工作 舊版 <script type="text/babel"> class Demo extends React.Component { state = { opacity : 1 } dead = ()=>{ //卸載組件 ReactDom.unmountComponentAtNode(document.getElementById('target')); } //父組件傳入一個新的props時調用,初始化頁面時不會調用 componentWillReceiveProps(props){ } //組件掛載完成後調用 componentDidMount(){ this.timer = setInterval(()=>{ let {opacity} = this.state; opacity -= 0.1; if(opacity <= 0) opacity = 1; this.setState({opacity}); },200) } //組件卸載前 componentWillUnmount(){ clearInterval(this.timer); } //初始化渲染、狀態更新時調用 render(){ return ( <form> <h1>{this.props.pass]</h1> <div style={this.state.opacity}>測試</div> <button onClick={this.change}>結束</button> </form> ) } } class DemoFoo extends React.Component { state = { test : 1} change = ()=>{ const {test} = this.state; this.setState({test : test++}) } render(){ return ( <form> <Demo pass={this.state.test} />測試</div> <button onClick={this.change}>修改</button> </form> ) } } </script> 掛載流程 1. constructor 2. componentWillMount 3. render 4. componentDidMount 畫面初始化觸發 更新流程 1. componentWillReceiveProps 由父組件觸發 2. shouldComponentUpdate 會判斷是否需要重新render 需要return Boolean 3. componentWillUpdate 4. render 5. componentDidUpdate setState (改狀態) : 2 -> 3 -> 4 -> 5 forceUpdate (強制更新,無法改狀態): 3 -> 4 -> 5 父組件render時子組件 1 -> 2 -> 3 -> 4 -> 5 卸載 1. ComponentWillUnmout 卸載 由ReactDom.unmountComponentAtNode() 觸發 新版 17~ 因這三個hook在未來異步渲染可能造成重大bug,因此被改為須加上前綴UNSAFE_ 才能使用 componentWillMount => UNSAFE_componentWillMount componentWillUpdate => UNSAFE_componentWillUpdate componentWillReceiveProps => UNSAFE_componentWillReceiveProps 掛載流程 1. constructor 2. getDerivedStateFromProps 3. render 4. componentDidMount 畫面初始化觸發 更新流程 1. getDerivedStateFromProps 2. shouldComponentUpdate 3. render 4. getSnapshotBeforeUpdate 5. componentDidUpdate setState (改狀態) : 1-> 2 -> 3 -> 4 -> 5 forceUpdate (強制更新,無法改狀態): 1 -> 3 -> 4 -> 5 父組件render時子組件 1 -> 2 -> 3 -> 4 -> 5 卸載 1. ComponentWillUnmout 卸載 由ReactDom.unmountComponentAtNode() 觸發 --- **方法介紹** getDerivedStateFromProps : 需要為static且回傳state obj | null 可傳入一個props及state 若是回傳一個state obj 則狀態不能再被改變,因為在新的生命週期此方法橫跨所有操作,因此狀態會在這邊被攔截 使用時機=>若state的值在任何時候都取決於props則可使用 getSnapshotBeforeUpdate : 需要回傳snapshot value ( any ) | null 回傳值會傳入componentDidUpdate 時間點為畫面更新前 componentDidUpdate: 可傳入 preProps , preState ,snapshotValue 時間點為畫面更新後,可搭配snapshotValue使用