本文為學習 React 16.8 版本以前的 class component 相關知識,以及 class vs fn component 的差異;內有基礎介紹、如何應用、class component 的生命週期以及兩者概念差異比較
一、什麼是 class component?
在 React 16.8 版本之前,沒有 hook,因此大家都用 class 寫 component,在這裡的學習目的是,有些舊的專案還是有可能會看到這個語法,建議知道一下比較好。
要怎麼寫?
1. 需要 ES6 class and this 的先備知識
寫一個名字叫 Button 的 class component
class Button extends React.Component {
render() {
const { onClick, children } = this.props;
return <button onClick={onClick}>{children}</button>;
}
}
2. 通常出現這個錯誤都代表 this 的值有錯:
"TypeError: Cannot read property 'props' of undefined"
解法就是:
a. 利用 constructor 把 this 的值綁定 .bind()
b. 寫成類似箭頭函式的寫法(長得很像,但有點不一樣)
參考資料:
React Quick Tip: Use Class Properties and Arrow Functions to Avoid Binding this
to Methods
React | 那個在 Class Component 中的 Arrow function (箭頭函式)
二、Class component 的生命週期
以 counter 為例解釋 Class component 的生命週期
import React from 'react';
export default class Counter extends React.Component {
constructor(props) {
super(props);
// 唯一可以指定初始值的地方只有在 constructor
// 其他地方都要用 setState()
this.state = {
counter: 1,
};
console.log('constructor')
}
// React 內建的生命週期 method
componentDidMount() {
console.log('did mount', this.state)
}
componentDidUpdate(prevProps, prevState) {
console.log('prevState:', prevState)
console.log('update!')
}
componentWillUnmount() {
console.log('unmount')
}
handleClick = () => {
this.setState({
counter: this.state.counter + 1,
});
};
render() {
const { counter } = this.state;
console.log('render')
return (
<div>
<button onClick={this.handleClick}>+1</button>
counter: {counter}
</div>
);
}
}
1. 生命週期裡面有幾個 React 的 method,因為是 React 內建,所以 this 的值已經設定好了。
a. componentDidMount()
: component mount 以後執行
b. componentWillUnmount()
: component unmount 之前(意指把 component 從畫面上去除,不 render 它的時候)
c. componentDidUpdate()
: component update 之後,會給你前一次的 props & state 兩個參數
2. 執行上面的程式碼,會依序印出什麼呢?
a. 畫面上有一個 counter 計數器,當第一次 render 時,會先印出 constructor -> render -> did mount;did mount 只會印出一次,就是 component 放到畫面上時。
當按下 +1 的按鈕時(state 改變時),會印出 render -> prevState -> update!
unmount 只有在 component 不被 render 時才會出現。
PS: 有一些 method 已經被 React deprecated 例如 componentWillMount()
就不建議使用了。
b. shouldComponentUpdate()
介紹
b.1 當某些條件發生時,禁止 React update,跟 React 效能優化比較有關
// 如果回傳 false 就不會 update
shouldComponentUpdate(nextProps, nextState) {
if (nextState.counter > 5) return false;
return true;
}
b.2 或用 PureComponent
一開始在這裡寫成這樣:
export default class Counter extends React.PureComponent
,React 會自動幫你優化
b.3 react class component lifecycle:
3. fn component & class component 的不同
影片在 FE302 > Function component vs Class component > Class component 的生命週期 11'59"
a. class component 所用的方式是「每個生命週期都有對應的 method,要做事時就把東西寫在裡面」
b. fn component 什麼東西都寫在 fn 裡面,每次執行都會 render 一次,生命週期的方式改用成 useEffect()
,fn component 這裡有介紹:React.Component