iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Modern Web

雙向奔赴的websocket與冰冷的react系列 第 18

[day18]React優化(2)Component vs memo

  • 分享至 

  • xImage
  •  

React 中,PureComponent 和 React.memo 是兩個常用來優化性能的工具,它們的作用是幫助 React 自動對比 props 的變化,並只在 props 改變時才重新渲染子組件,從而避免不必要的渲染。

對照組

import React, { useState } from 'react';

// 普通的子組件
const ChildComponent = ({ count }) => {
    console.log('ChildComponent 重新渲染');
    return <div>計數: {count}</div>;
};

function App() {
    const [count, setCount] = useState(0);
    const [input, setInput] = useState('');

    return (
        <div>
            <h1>React 優化對照組</h1>
            <ChildComponent count={count} />
            <button onClick={() => setCount(count + 1)}>增加計數</button>
            <input value={input} onChange={(e) => setInput(e.target.value)} />
        </div>
    );
}

export default App;

觀察變化:

每次你更改輸入框的值,App 組件重新渲染,子組件 ChildComponent 也會重新渲染,即使它的 props 沒有改變。你會在控制台中看到 "ChildComponent 重新渲染" 每次輸入變更時出現,這就是性能浪費的情況。

使用 PureComponent

  • PureComponent 自動進行 props 的淺比較,當 props 沒有變化時,它會阻止子組件重新渲染。
import React, { useState, PureComponent } from 'react';

// 使用 PureComponent 優化子組件
class ChildComponent extends PureComponent {
    render() {
        console.log('ChildComponent 重新渲染');
        return <div>計數: {this.props.count}</div>;
    }
}

function App() {
    const [count, setCount] = useState(0);
    const [input, setInput] = useState('');

    return (
        <div>
            <h1>React 優化實驗組 - PureComponent</h1>
            <ChildComponent count={count} />
            <button onClick={() => setCount(count + 1)}>增加計數</button>
            <input value={input} onChange={(e) => setInput(e.target.value)} />
        </div>
    );
}

export default App;

結果

  • 當你更改 input 值時,ChildComponent 不會重新渲染,因為 PureComponent 自動對比 props,發現 count 沒有變化。
  • 只有當 count 改變時,ChildComponent 才會重新渲染。

如果忘記props可以去看一下父子組件,所以可從觀察中發現發現PureComponent專注於組件的渲染控制。

使用 React.memo

  • React.memo 是函數組件中的優化工具,與 PureComponent 類似,它會根據 props 的變化來決定是否重新渲染組件。
import React, { useState, memo } from 'react';

// 使用 React.memo 優化子組件
const ChildComponent = memo(({ count }) => {
    console.log('ChildComponent 重新渲染');
    return <div>計數: {count}</div>;
});

function App() {
    const [count, setCount] = useState(0);
    const [input, setInput] = useState('');

    return (
        <div>
            <h1>React 優化實驗組 - React.memo</h1>
            <ChildComponent count={count} />
            <button onClick={() => setCount(count + 1)}>增加計數</button>
            <input value={input} onChange={(e) => setInput(e.target.value)} />
        </div>
    );
}

export default App;

結果

  • React.memo 會對 props 進行淺比較。當你更改 input 時,ChildComponent 不會重新渲染。
  • 只有當 count 改變時,ChildComponent 才會重新渲染。

跟上面那個挺像的,但是一個支援定義出來的函數一個不支援(範例const a=function ...),所以根據現代趨勢多已後者使用為多,至於他們的觀察對象都是組件的props。

兩者區別

特性 PureComponent React.memo
適用對象 類組件 函數組件
比較方式 自動淺比較,不支持自定義 默認淺比較,支持自定義比較函數
語法靈活性 只能用於類組件 只適用於函數組件
應用場景 傳統 React 應用,類組件 現代 React 應用,函數組件和 Hooks
自定義比較邏輯 不支持 支持,自定義函數可以控制何時渲染

總結

總結這兩篇的優化

特性 PureComponent / React.memo useMemo / useCallback
目的 優化子組件的渲染,避免不必要的重渲染 優化函數和計算的記憶,避免不必要的重新計算或函數創建
應用場景 防止子組件在 props 沒變時重新渲染 防止每次渲染時重新計算值或重新創建函數
使用對象 子組件的 props 比較(基於淺比較) 計算值或函數的記憶
使用方式 PureComponent 用於類組件,React.memo 用於函數組件 useMemo 記憶計算結果,useCallback 記憶函數
如何工作 自動對 props 進行淺比較,只有 props 發生變化時才重新渲染 通過依賴項控制函數或值的重新計算或創建,只有依賴變化時才更新

今天就這樣囉


上一篇
[day17]React優化(1)useMemo 和 useCallback
下一篇
[day19]Redux 介紹與配置成store
系列文
雙向奔赴的websocket與冰冷的react30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言