LoginSignup
0
0

More than 1 year has passed since last update.

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

Last updated at Posted at 2023-02-04

直前の記事に続いて、子供コンポーネントに関数propsを追加して渡せば、どのような状況になるでしょ

Comments.jsx
import React, { useCallback } from 'react'
import CommentItem from './CommentItem'

export default function Comments({commentList}) {
  // onClickイベントハンドラー関数
  const handleChange1 = (() => {
       console.log("push");
  });
  return (
    <div>
        {commentList.map(comment => <CommentItem 
            key={comment.id}
            title={comment.title}
            content={comment.content}
            likes={comment.likes}
            onClick={handleChange}
            />
        )}
    </div>
  )
}

Comments.jsxのCommentItem propsに固定のonClickを設けて、

CommentItem.jsx
import React, { Profiler, memo } from 'react'
import './CommentItem.css'

function CommentItem({title, content, likes, onClick}) {
    function onRenderCallback(
        id,
        phase,
        actualDuration, 
        baseDuration,
        startTime,
        commitTime,
        interactions 
      ) {
        // レンダリング度にログを出力する!
        console.log(`actualDuration(${title}: ${actualDuration})`);
      }
    const handleClick = () => {
        onClick();
    }
   return (
      <Profiler id="CommentItem" onRender={onRenderCallback}>
        <div className="CommentItem" onClick={handleClick}>
            <span>{title}</span>
            <br />
            <span>{content}</span>
            <br />
            <span>{likes}</span>
        </div>
    </Profiler>
  )
}
export default memo(CommentItem); // memoはHOC!

CommentItemのeventHandlerに追加して、memoizationが効くのかを検証!

結果は以下。
結果からわかるように、前回のレンダ結果を再使用せず、また最初からレンダリングした結果を出しています。
스크린샷 2023-02-04 09.34.46.png

その理由としては、Memoizationの時にreactはpropsを比較して再使用するかを決めています。
上記では、Commentsに関数のpropsを新しく追加したので、reactは前Propsと現Propsを比較し、違うものと判断して
再レンダリングしちゃいます。
(shallow compare : 基本タイプデータの場合、値が同一かどうかだけを比較。
オブジェクトの場合は、参照だけを比較する。値が同じでも、参照値が異なるため、再レンドリンが発生する。)

この場合に使用できるのが{ useCallback } HOOKです。
useCallbackは関数(Object)をmemoizationしてくれます。
useCallbackは、関数を保存するhookです。reactに関数を保存し、実行ごとに再生成しないようにします。
メモリ内の同一の場所のいずれかに保存されるため、同一の関数(オブジェクト)であるか比較することができます!

Comments.jsx:useCallback適用
  import React, { useCallback } from 'react'
  // (・・・省略)

  //修正前
  const handleChange1 = (() => {
       console.log("push");
  });
  //修正後
  const handleChange = useCallback(() => {
      console.log("push");
  }, []);

10個のコンポーネントが作成された時点のログです。
useCallbackを使う前とは違く、ちゃんと前回の結果が再使用されていることがわかります。
image.png

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