avoid_react_re-rendering

February 09, 2020

Example Component: Counter

常見的範例 React Component: Counter

const Title = () => {
  console.log('Title rendering!');
  return (
    <div>
      <h1>Counter</h1>
    </div>
  );
};

const Counter = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <Title />
      <span>{`目前計數:${count}`}</span>
      <button type="button" onClick={() => { setCount(count + 1); }}>
        點我加一
      </button>
    </div>
  );
};

每次點下 add 1 按鈕,
Counterstate 都會更新,
整個 Counter 會進行 re-render。

連帶會使沒有任何改變的 <Title /> 也進行 re-render。

keep_re-rendering

PureComponent, shouldComponentUpdate

上述中的 <Title /> 的 re-render 就沒有實質作用,
可以被節省的情況。

在傳統的 Class based Component 中,
可以用 PureComponentshouldComponentUpdate 處理

React.memo

在使用 Function Component 的狀況下,
想要有 PureComponent 的效果,
最直接的方法就是在外面套上 React.memo()

const Title = props => {
    ...
}

const ReactMemoTitle = React.memo(Title)

此時的 ReactMemoTitle 就具有 PureComponent 的特性,
props 沒有變動的情況下不會 re-render


import React, { useState } from 'react'

const Title = props => {
  const { title } = props

  console.log(`${title} is rendering!`)

  return (
    <div>
      <h1>{title}</h1>
    </div>
  )
}

const ReactMemoTitle = React.memo(Title)

const Counter = props => {
  const [count, setCount] = useState(0)

  return (
    <div>
      <section>
        <Title
          title='Normal Title'
        />
      </section>
      <section>
        <ReactMemoTitle
          title='ReactMemo Title'
        />
      </section>

      <div>{`current count::${count}`}</div>

      <button
        type='button'
        onClick={() => {
          setCount(count + 1)
        }}
      >
        add 1
      </button>
    </div>
  )
}

export default Counter

only_normal_title_re-rendering

useMemo

useCallback

references

React | 關於 Component 效能優化的那件小事 - StarBugs Weekly 技術專欄 - Medium

github

sss63232/avoid_react_re-rendering


Profile picture

Written by YU-HSIN, CHEN,
Front-end Engineer at PayPay Corporation.,
Loves pursuing modern web development.Find me on LinkedIn