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

<h2>useMemoの使用方法</h2>

```react: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を新しく設ける。
```react
   const [clickCount, setClickCount] = useState(0);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/773fbeb8-67b4-57be-fa95-c5c976715a58.png)
下は、ログです。
memoizationした前回のコンポーネントは2度とレンダリングされずに、新しく追加したコンポーネントのみログが出力されていることがわかります！rate check ログはレンダリング度に実行されるrate()のログ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/ad059a42-6525-91f9-c5ef-992f9a9a59cb.png)
コンポーネントを押下すると、「onClick={handleClick}」により押下したコンポーネントがリレンダリングされます。
押下コンポーネントのProfileログとuseCallback hookのonClick()、rate()が呼ばれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/6e2b2285-b417-54d4-b031-12b6d644a1c8.png)
useCallback hookのonClick()　→　pushed
rate()　→　rate check 
![스크린샷 2023-02-05 20.38.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/8dd9cc0f-9b3c-196b-00f4-a9b86dfdee31.png)

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/27868ed2-2fc6-1319-994a-d928d00d4f02.png)
コンポーネントをクリックした時に、いいねの数を評価するrate()は、再度レンダリングされなくなったことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/a7c4899f-10e7-1f35-2fa5-2a6a4ebff3d0.png)
<h2>useCallbackとuseMemoの違い</h2>
React.memo：レンダリングする時に、レンダ前のコンポーネントのpropsと今回のpropsを比較して、再使用するかを決める！
特定の関数をmemoizationしたい時に使用するhookがuseCallbackを、
特定のpropsをmemozationしたい時に使用するhookはuseMemo！