又是生命週期~
生命週期
一個 component 的生命週期主要能分成三個階段:
另外先提醒一下,等一下介紹的 method 都會自動綁定 this 值(因為是 React 幫你呼叫這些 method 的),所以不用像寫 handler
那樣要自己綁定。
Mount 階段
在 Mount 主要會經歷這幾段:
- 執行 constructor 初始化
static getDerivedStateFromProps
會在 render 前觸發,但不用管這個
componentWillMount
,mount 以前,但不推薦使用,也應該快被廢棄了。
render
執行 render method
componentDidMount
,mount 之後,適合在這個階段打 API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Demo extends React.Component { constructor(props) { console.log("constructor"); super(props); this.state = { counter: 0, }; } componentWillMount() { console.log("before mount"); }
componentDidMount() { console.log("after mount"); } render() { console.log("render"); return ( <div> <div>counter: {this.state.counter}</div> <button onClick={this.handleClick}>+1</button> </div> ); } }
|
Update 階段
在 Update 主要會經歷這幾段:
shouldComponentUpdate
在 update 之前,可以在這裡決定要不要更新 component(回傳 true
或 false
)
componentWillUpdate
在確定會更新後,真的更新東西以前(也是會廢棄的東西,知道一下就好)
render
,執行 render method
componentDidUpdate
已經更新完東西了,這邊會順便給你更新前的 props 和 state
接下來這個示範是每次 update 以前會先用 shouldComponentUpdate
檢查,確認更新後的值是否 < 5,符合的話才進行更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class Demo extends React.Component { constructor(props) { console.log("constructor"); super(props); this.state = { counter: 0, }; }
componentWillUpdate() { console.log("before update"); }
componentDidUpdate(prevProps, prevState) { console.log("after update"); console.log("prevState", prevState); }
shouldComponentUpdate(nextProps, nextState) { console.log("shouldComponentUpdate"); return nextState.counter < 5; }
handleClick = () => { this.setState({ counter: this.state.counter + 1, }); };
render() { console.log("render"); return ( <div> <div>counter: {this.state.counter}</div> <button onClick={this.handleClick}>+1</button> </div> ); } }
|
UnMount 階段
這個就相對簡單一些,就是在元件要被從畫面上移除之前可以用 componentWillUnmount
來做事情。
這個示範是當 counter < 1
的時候才顯示 TestText
元件,所以當不符合時 TestText
就會被移除掉,觸發 componentWillUnmount
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class TestText extends React.Component { componentDidMount() { console.log("TestText after mount"); }
componentWillUnmount() { console.log("TestText before unmount"); }
render() { return <div>yoyoyo</div>; } }
class Demo extends React.Component { constructor(props) { console.log("constructor"); super(props); this.state = { counter: 0, }; }
handleClick = () => { this.setState({ counter: this.state.counter + 1, }); };
render() { console.log("render"); return ( <div> <div>counter: {this.state.counter}</div> <button onClick={this.handleClick}>+1</button> {this.state.counter < 1 && <TestText />} </div> ); } }
|
以上就是基本的生命週期,只要知道在每個階段都會有對應的 method 可以使用就差不多了。
PureComponent
最後補充一下 PureComponent
這東西。
前面有介紹可以用 shouldComponentUpdate
來決定要不要觸發 Component 的更新,但如果要自己寫好像蠻麻煩的?
因此 React 有提供 PureComponent
,只要在創造 Component 時用它,它就會自動幫你設定 shouldComponentUpdate
,只有在 props 改變時才觸發更新(跟 hook 的 memo
差不多)
1 2 3 4
| class Demo extends React.PureComponent { ... }
|