Published on

React.memoの使い方と使い道を解説

Authors
  • avatar
    Name
    ssu
    Twitter

React.memoはReactでDOMをレンダーのパフォーマンスを最適化する際に使われます。 すなわち、React.memoを適切に使うことで、viewの描画速度を早めることでき、 ユーザの利便性や体験を向上させることができます。

ただし、正しく使わないと最適化できないので、React.memoの正しい使い方を例を交えて紹介したいと思います。

例えば、下記のように好きな食べ物を表示するコンポーネント(FavaoriteFood)があり、 またCounterがあるときに、countの状態が変化するたびに、FavaoriteFoodコンポーネントも再描画されてしまいます。本来は、FavoriteFoodのstateは変更されていないので、再描画されるべきではないですが、 親であるAppの状態が変わるので、再度描画されていまいます。(実際のコードを動かすと、counterをインクリメントすると、App is calledFavoritFood comp is calledが呼ばれconsoleに出力されます。)

このような時は、Counterもコンポーネント化して、親(App)にstateを持たせなければ、Counterの状態が変更してもFavoriteFoodの描画はされなくなります。

ただ実際には、このように親コンポーネントでなんらかの状態管理されており、その状態が変化し、 その都度、子のコンポーネントが意図せずに描画されてしまう場合があると思います。

そのような時に、React.memoを使うと状態が変わっていないFavoritFoodの再描画防ぐことができます。

import { useState } from "react"; const FavoriteFood = ({food}) => { const [msg, setMessage] = useState('') console.log('FavoriteFood comp is called') return ( <> <p>好きな食べ物は: {msg}</p> { msg ? ( <button onClick={ () => setMessage('') }>隠す</button> ) : ( <button onClick={ () => setMessage(food) }>好きな食べ物を表示する</button> ) } </> ) } const App = () => { const [count, setCount] = useState(0) console.log("App is called") return ( <> <p>{count}</p> <button onClick={() => setCount(count + 1)}>++</button> // <FavoriteFood food="りんご" /> </> ); } export default App;

React.memoを使った場合

import React, { useState } from "react"; const FavoriteFood = React.memo(({food}) => { const [msg, setMessage] = useState('') console.log('FavoriteFood comp is called') return ( <> <p>好きな食べ物は: {msg}</p> { msg ? ( <button onClick={ () => setMessage('') }>隠す</button> ) : ( <button onClick={ () => setMessage(food) }>好きな食べ物を表示する</button> ) } </> ) }) const App = () => { const [count, setCount] = useState(0) console.log("App is called") return ( <> <p>{count}</p> <button onClick={() => setCount(count + 1)}>++</button> <FavoriteFood food="りんご" /> </> ); } export default App;

上記のようにFavoriteFoodをReact.memoで書こうと、 FavoriteFoodのプロパティであるfoodやFavoriteFoodの状態が変更されない限りFavoriteFoodは再度描画されなくなります。もしこのFavoiteFoodが重たい処理である場合に、再度描画されないことで大きくパフォーマンスを向上することができます。

それがReact.memoを使ってメモ化することの利点となります。

また、useCallbackはreact.memoとよく一緒に使われるものなので、useCallbackの使い方と使い所も参考にしてみてください。

参考: Use React.memo() wisely

参考: React.memo