React class component 的生命週期

又是生命週期~

生命週期

一個 component 的生命週期主要能分成三個階段:

  • Mount
  • Update
  • Unmount

life-cycles

另外先提醒一下,等一下介紹的 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>
);
}
}

mount

Update 階段

在 Update 主要會經歷這幾段:

  • shouldComponentUpdate 在 update 之前,可以在這裡決定要不要更新 component(回傳 truefalse
  • 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);
// 只能是 Object
this.state = {
counter: 0,
};
}

componentWillUpdate() {
console.log("before update");
}

// 會給你上一次的 props 和 state
componentDidUpdate(prevProps, prevState) {
console.log("after update");
console.log("prevState", prevState);
}

// return true ? 更新 : 不更新
// 會提供更新後的 props 跟 state
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
// 小於 5 才更新
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>
);
}
}

update

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");
}

// unmount 以前
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>
);
}
}

unmount

以上就是基本的生命週期,只要知道在每個階段都會有對應的 method 可以使用就差不多了。

PureComponent

最後補充一下 PureComponent 這東西。

前面有介紹可以用 shouldComponentUpdate 來決定要不要觸發 Component 的更新,但如果要自己寫好像蠻麻煩的?

因此 React 有提供 PureComponent,只要在創造 Component 時用它,它就會自動幫你設定 shouldComponentUpdate,只有在 props 改變時才觸發更新(跟 hook 的 memo 差不多)

1
2
3
4
class Demo extends React.PureComponent {
// 每當 props 改變時才更新
...
}
React 的第八個 hook:useContext 與 createContext 初探 Class-component
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×