---
# System prepended metadata

title: Class Component
tags: [Note]

---

---
tags: Note
---

# Class Component
要定義一個 React component class，需要繼承（extend）React.Component

### 寫法
```
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

# 先上生命週期
[先上圖](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)
![](https://i.imgur.com/D8uILGJ.png)


## Mounting
當一個組件的 instance 被建立且加入 DOM，生命週期會依照下面順序呼叫
- constructor
- static getDerivedStateFromProps()
- render()
- componentDidMount()

## Updating
當 prop 或 state 有變化時，就會 updating，當一個組件被重新 render 時，生命週期將會依照下面順序呼叫
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()



## Unmounting
當一個組件被從 DOM 中移除時會呼叫
- componentWillUnmount()

## error
當組件在 render 過程、生命週期、或在某個子組件的 constructor 中發生錯誤時會呼叫

- static getDerivedStateFromError()
- componentDidCatch()

---

# 常用的生命週期方法

## constructor()
一個 React component 的 constructor 會在其被 mount 之前被呼叫
> 幫 React.Component subclass 建立 constructor 時，要在其他任何宣告之前呼叫 super(props)，不然 this.props 在 constructor 中的值會出現 undefined
### 寫法
```
constructor(props)
```
### 說明
- 透過指定一個 this.state 物件來初始化內部 state
- 為 event handler 方法綁定 instance
- 不要在 constructor() 中呼叫 setState()，想用內部 state，就在 constructor 把最初的 state 指定為 this.state
- 避免在 constructor 中產生任何 side effect 或 subscription

---

## componentDidMount()
組件被 mount（加入 DOM tree 中）後，componentDidMount() 會馬上被呼叫
### 寫法
```
componentDidMount()
```
### 說明
- 要 DOM 節點初始化寫在這
- 在這請求資料
- 這裡適合設立任何 subscription（但後續要取消）
- 可以馬上呼叫 setState()，呼叫會觸發一次額外的 render，但會在瀏覽器更新螢幕之前發生（謹慎使用）

---

## componentDidUpdate()
componentDidUpdate() 會在更新後馬上被呼叫（不會在初次 render 時被呼叫）
### 寫法
```
componentDidUpdate(prevProps, prevState, snapshot)
```
### 說明
- 這裡也適合做網路請求
- 可以馬上呼叫 setState()，但為它設置條件不然會無限迴圈

---

## componentWillUnmount()
componentWillUnmount() 會在ㄧ個組件被 unmount 和 destroy 後馬上被呼叫
### 寫法
```
componentWillUnmount()
```
### 說明
- 這裡可以做一切的清除，像是取消計時器、網路請求、移除任何在 componentDidMount() 內建立的 subscription
- 不要呼叫 setState()，因為這裡不會再重新 render，當一個組件的instance 被 unmount 後，就永遠不會再被 mount。

---

# 比較不常用的生命週期方法

## shouldComponentUpdate()
用 shouldComponentUpdate() 來讓 React 知道一個組件的 output 並不會被目前在 state 或 prop 內的改變所影響
> React 的預設行為是每當 state 有所改變時就重新 render，大多情況下按照這個預設行為。
### 寫法
```
shouldComponentUpdate(nextProps, nextState)
```
### 說明
- 這方法是為了效能最佳化

---

## static getDerivedStateFromProps()
getDerivedStateFromProps 會在一個組件被 render 前被呼叫
### 寫法
```
static getDerivedStateFromProps(props, state)
```
### 說明
- 每一次 render 時都會被觸發
- 這個方法是為了某些很少見的例子而存在的，像是有時 state 會依賴 prop 在一段時間過後所產生的改變

---

## getSnapshotBeforeUpdate
getSnapshotBeforeUpdate() 在提交最新 render 的 output 之前立即被調用
### 寫法
```
getSnapshotBeforeUpdate(prevProps, prevState)
```
### 說明
- 這個方法回傳的任何值會被當作一個參數傳遞給 componentDidUpdate()。

### 情境
在像是對話串這類需要以某種特殊方式處理滾動軸位置的 UI 中出現

---

## static getDerivedStateFromError()
在某個錯誤被一個 descendant component 拋出後被呼叫，接收該錯誤為其參數並回傳一個值以更新 state
### 寫法
```
static getDerivedStateFromError(error)
```

---

## componentDidCatch()
會在某個錯誤被一個 descendant component 拋出後被呼叫
### 寫法
```
componentDidCatch(error, info)
```
### 說明
- 接收兩個參數
    - error：被拋出的錯誤
    - info

---

# 資料來源
[React Doc](https://zh-hant.reactjs.org/docs/react-component.html#constructor)