プログラミング技術

本サイトはプロモーションが含まれています。

React.memoの使い方。パフォーマンスアップ【Reactの学習】

react.memoの使い方
初心者さん
Reactでパフォーマンスアップのコツは、不要な再レンダリングを抑えることだよね...。

今回は、Reactのパフォーマンスを悪くする再レンダリングについてです。

▼この記事で理解できる内容は以下になります。

  1. React.memoの使い方
  2. React.memoを使う場合、使わない場合の比較

この記事は、React初心者の方、React.memoについて知りたい方を対象としています。

React.memoってどんな機能?

React.memoはどのようにパフォーマンスアップさせるのかReact公式の内容を見ると参考になります。

React.memoは使い道

頻繁に再レンダリングされるコンポーネントで、書き換える必要のない子コンポーネントがぶら下がっている場合に利用するとパフォーマンスアップにつながる。

React.memoは最後のレンダリングを記憶している

もしあるコンポーネントが同じ props を与えられたときに同じ結果をレンダーするなら、結果を記憶してパフォーマンスを向上させるためにそれを React.memo でラップすることができます。つまり、React はコンポーネントのレンダーをスキップし、最後のレンダー結果を再利用します。
引用元: React公式

前回レンダーされた結果を記憶しているため、同じ内容であれば再レンダリングを行わないためパフォーマンスアップにつながる。

propsの変更のみチェックしている

React.memo は props の変更のみをチェックします。
引用元: React公式

子のコンポーネントでReact.memoが使われている場合、propsの変更のみチェックしているため、変更がない場合は再レンダリングを行わないためパフォーマンスアップにつながる。

React.memoの使い方

React.memoはラップするだけで簡単に利用することができます。

React.memoの基本形

const SampleMemo = React.memo(props => {
  return <p>{props.memo}</p>
});

React.memoの使用例

親コンポーネントにある2つのボタンをクリックし、React.memoを使っている子コンポーネントと使っていない子コンポーネントのレンダリングの動作を確認してみます。

Vue.jsではcomputedが、それに近い動きをします。computed内にあるプロパティに変化がない場合は再レンダリングが行われません。

以下のようなサンプル画面を準備しました。

▼サンプルの画面

React.memo

親コンポーネントに2つのボタンとボタンクリックした時にカウントアップされる値をpropsで受け取る子コンポーネントです。

子コンポーネントは、片方の「NormalCountコンポーネント」は特に何もしていない子コンポーネント。

「MemoCountコンポーネント」は、React.memoを利用した子コンポーネントです。それぞれTypeScriptで書いています。

親コンポーネント

import React, { useState } from 'react'
import NormalCount from './components/NormalCount'
import MemoCount from './components/MemoCount'

export default function App() {
  const [normalCount, setNormalCount] = useState(0)
  const [memoCount, setMemoCount] = useState(0)

  return (
    <div>
      <NormalCount normalCount={normalCount}/>
      <MemoCount memoCount={memoCount}/>
      <button onClick={() => setNormalCount(normalCount + 1)}>NORMAL</button>
      <button onClick={() => setMemoCount(memoCount + 1)}>MEMO</button>
    </div>
  )
}

NormalCountコンポーネント

import React from 'react'

interface NormalProps {
  normalCount: number
}
const NormalCount: React.FC<NormalProps> = (({ normalCount }) => {

  console.log('■ Normal Count')
  return (
    <div>
      <p>normalCount: {normalCount}</p>
    </div>
  )
})

export default NormalCount

MemoCountコンポーネント

import React from 'react'

interface MemoProps {
  memoCount: number
}

const MemoCount: React.FC<MemoProps> = React.memo(({ memoCount }) => {

  console.log('▼ Memo Count')
  return (
    <div>
      <p>memoCount: {memoCount}</p>
    </div>
  )
})

export default MemoCount

React.memoの使用した結果

「MEMOのボタン」を押下した場合は、NormalCountコンポーネントの方の値に影響がなくても再レンダリングされています。

逆に「NORMALのボタン」を押下した場合は、React.memoでラップされたMemoCountコンポーネントのpropsの値に影響がないため再レンダリングされていないのがわかります。

React.memoの使い方まとめ

今回のように軽いコンポーネントの場合は、パフォーマンスに影響がでることはないと思いますが、レンダリングに時間がかかるコンポーネントなどで毎回再レンダリングされると、パフォーマンスに影響します。

頻繁に値が変化するようなアプリの場合は、React.memoの利用も考えながらコンポーネントを作っていきたいですね。

  • この記事を書いた人
くろめがね

くろめがね

10年以上Web開発会社でWebエンジニアとして経験を積む。管理職・採用担当を経て2020年フリーランスエンジニアになりました。 80 - 140くらいの開発案件に参画。 元プログラミングスクール運営企業の社員。 【開発】 Java / PHP / Ruby / Golang / Vue.js(Nuxt.js) / React(Next.js) / AnglarAWSのCognito、Lambdaが楽しい。

-プログラミング技術