Day06 : Component 的三種長相


在 React 定義一個組件,有三種組件長相:

  1. Class Component
  2. Function Component
  3. 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,可以參考這篇,我也是看了這篇才知道原來背後原理是這樣。

#React







你可能感興趣的文章

[進階 js 04] Scope 變數的生存範圍

[進階 js 04] Scope 變數的生存範圍

VSCode安裝

VSCode安裝

什麼是 API? SOAP? 其他 HTTP API?

什麼是 API? SOAP? 其他 HTTP API?






留言討論