在 React 定義一個組件,有三種組件長相:
- Class Component
- Function Component
- Pure Component
這三種會在不同的情境下選擇使用,會依照該組件組成決定使用哪個。
Class Component
當組件需要定義狀態 state
、方法時,可以使用 Class Component,是最常看到的,因為 state
可以妥妥地定義在 Class Component。
class CounterText extends Component {
render(){
return (
<div>
<h1>{this.props.num}</h1>
</div>
)
}
}
class Counter extends Component {
state = {
count: 1
}
addCount = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<CounterText num={this.state.count}/>
<button onClick={this.addCount}>+1</button>
</div>
);
}
}
CounterText 組件單純顯示數字。
Functional Component
又被稱為無狀態組件,單純做一個回傳 HTML 結構的組件,不會有任何的 state
,不過可以透過 Function
可以傳入參數的特性來傳入 props
:
const CounterText = (props) => {
return (
<div>
<h1>{props.num}</h1>
</div>
)
}
將 CounterText 改寫成函式組件
CounterText 這種單純顯示父組件的值的組件,很適合撰寫成 Functional Component,因為它不需要自己的組件,它只要接受上面傳下來的值,它更不用 render Function,因為當父組件重新 render 時,它就會被再次呼叫、再次回傳 HTML Tag 回去 Counter 組件。
在這邊思考,是按下 button 後值會變的時候,組件才會重新 render 嗎?
const CounterText = (props) => {
alert('render CounterText')
return (
<div>
<h1>{props.num}</h1>
</div>
)
}
class Counter extends Component {
state = {
count: 1
}
addCount = () => {
this.setState({
count: this.state.count
})
}
render() {
alert('render Counter')
return (
<div>
<CounterText num={this.state.count}/>
<button onClick={this.addCount}>+1</button>
</div>
);
}
}
把 +1 拿掉,代表值並不改變,並且在兩個組件當中加上
alert
紀錄是否有重新 render。
這邊可以得知,即使值不變,組件依舊是重新 render,這邊就可以講到最後一個組件了!
Pure Component
當狀態的值並不會改變時,Pure Component 也不會重新 render,既然畫面都不會有所改變,為何還要 render 浪費效能?這也就是 Pure Component 存在的原因。
import React, { Component, PureComponent } from 'react';
const CounterText = (props) => {
alert('render CounterText')
return (
<div>
<h1>{props.num}</h1>
</div>
)
}
class Counter extends PureComponent {
state = {
count: 1
}
addCount = () => {
this.setState({
count: this.state.count
})
}
render() {
alert('render Counter')
return (
<div>
<CounterText num={this.state.count}/>
<button onClick={this.addCount}>+1</button>
</div>
);
}
}
將 Counter 改變成 PureComponent,請忽略你改完後 code 第一次的 alert,主要是看 button 的 event 觸發後的 render 情況。
從這可以得知,Pure Component並不會重新 render,因為 state
並沒有被改變,而既然 Counter 沒有重新 render,那 Functional Component 也不會被呼叫。
總結
雖然説 PureComponent 可以有效地選擇是否要重新 render,但也不代表所有你寫的 Component 都一定要改變成 PureComponent,可以參考這篇,我也是看了這篇才知道原來背後原理是這樣。