LoginSignup
0
0

More than 1 year has passed since last update.

React.Memoizationとは - useMemoを使ってリレンダリングを防ぐ

Last updated at Posted at 2023-02-05

useMemoの使用方法

CommentItem.jsx、useMemo使用しない場合
import React, { Profiler, memo, useState } from 'react'
import './CommentItem.css'

// 親コンポーネントから渡されたpropsを受け取る
function CommentItem({title, content, likes, onClick}) {
    const [clickCount, setClickCount] = useState(0);
    function onRenderCallback(
       // 省略・・・
      ) {
        console.log(`actualDuration(${title}: ${actualDuration})`);
      }
    // componentをクリックする時に実行されるイベントハンドラー
    const handleClick = () => {
        // prevは前clickCount state値
        setClickCount((prev)=> prev + 1);
        // onClickは親コンポーネントから受け取った、useCallback hook関数!
        onClick();
    }

    const rate = () => {
        console.log("rate check");
        return likes > 10 ? 'good' : 'bad';
    }

   return (
    // profileタグで、性能チェック範囲を囲む。
    <Profiler id="CommentItem" onRender={onRenderCallback}>
       <div className="CommentItem" onClick={handleClick}>
           <span>{title}</span>
           <br />
           <span>{content}</span>
           <br />
           <span> {likes}</span>
           <br />
           {/* いいね 管理*/}
           <span> {rate()} </span> 
           <br />
           <span>{clickCount}</span>
       </div>
    </Profiler>
  )
}

export default memo(CommentItem); // memo는 HCO

コンポーネントをクリックする時に、クリックした数を管理するclickCount Stateを新しく設ける。

   const [clickCount, setClickCount] = useState(0);

image.png
下は、ログです。
memoizationした前回のコンポーネントは2度とレンダリングされずに、新しく追加したコンポーネントのみログが出力されていることがわかります!rate check ログはレンダリング度に実行されるrate()のログ。
image.png
コンポーネントを押下すると、「onClick={handleClick}」により押下したコンポーネントがリレンダリングされます。
押下コンポーネントのProfileログとuseCallback hookのonClick()、rate()が呼ばれます。
image.png
useCallback hookのonClick() → pushed
rate() → rate check
스크린샷 2023-02-05 20.38.24.png

その中で、rate()はlikesを演算して、その数が10を超えると'good'を、以下なら'bad'を出力します。
結局、rate()はlikesに依存しています。
しかし上のロジックでは、コンポーネントの押下は、likes値に影響を与えてないのですが、likesを評価するrate()はいつも実行されます。そのため、likes値が変わる度にlikesを評価するrate()を実行させたいですね。

これのように、rate()はlikseに依存していてlikesが変わる時だけrate()を実行させたい時にuseMemoを使います。useMemoはlikesをmemoryに保存して、likesがupdateする時にrate()が実行するようにしてくれます。

useMemo使用方法
    // 1番目の引数にはcallback関数を
    // 2番目の引数にはdependancy arrayを定義します。
    // likesがupdate → callback実行!
    const rate = useMemo(()=>{
        console.log("rate check");
        return likes > 10 ? 'good' : 'bad';
    },[likes]); 
   // ・・・
   <span>rate:{rate} </span>

image.png
コンポーネントをクリックした時に、いいねの数を評価するrate()は、再度レンダリングされなくなったことがわかります。
image.png

useCallbackとuseMemoの違い

React.memo:レンダリングする時に、レンダ前のコンポーネントのpropsと今回のpropsを比較して、再使用するかを決める! 特定の関数をmemoizationしたい時に使用するhookがuseCallbackを、 特定のpropsをmemozationしたい時に使用するhookはuseMemo!
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0