🐥

useCallbackとuseMemoって何が違う?

2023/03/20に公開

結論

useMemo:関数を呼び出した結果をキャッシュします。
下の例では、computeRequirements(product) を呼び出した結果をキャッシュして、product が変更されない限り変更されないようにします。
これにより、ShippingForm を不必要に再レンダリングすることなく、要件オブジェクトを渡すことができます。 必要に応じて、React はレンダリング中に渡された関数を呼び出して結果を計算します。

useCallback:関数自体をキャッシュします。
useMemo とは異なり、提供する関数を呼び出しません。 代わりに、提供した関数をキャッシュして、productId または referrer が変更されない限り、handleSubmit 自体が変更されないようにします。
これにより、ShippingForm を不必要に再レンダリングすることなく、handleSubmit 関数を渡すことができます。 ユーザーがフォームを送信するまで、コードは実行されません。

import { useMemo, useCallback } from "react";

function ProductPage({ productId, referrer }) {
  const product = useData("/product/" + productId);

  const requirements = useMemo(() => {
    // Calls your function and caches its result
    return computeRequirements(product);
  }, [product]);

  const handleSubmit = useCallback(
    (orderDetails) => {
      // Caches your function itself
      post("/product/" + productId + "/buy", {
        referrer,
        orderDetails,
      });
    },
    [productId, referrer]
  );

  return (
    <div className={theme}>
      <ShippingForm requirements={requirements} onSubmit={handleSubmit} />
    </div>
  );
}

useCallback とは

再レンダリング間で関数定義をキャッシュできる ReactHooks です。

const cachedFn = useCallback(fn, dependencies);
  • 引数:

fn キャッシュする関数
任意の引数をとり、任意の値を返すことができる
関数を返します(呼び出しません。)

dependencies 依存関係
fn コード内で参照されるすべてのリアクティブ値のリスト。リアクティブ値には、props、state、およびコンポーネント本体内で直接宣言されたすべての変数と関数が含まれます。

  • 返り値:

最初のレンダリングで、useCallback は渡された fn 関数を返します。
それ以外の場合は、現在のレンダリング中に渡した関数を提供し、後で再利用できるように保存します。React は関数を呼び出しません。関数が返されるので、呼び出すタイミングと呼び出すかどうかを決定できます。

useMemo とは

const cachedValue = useMemo(calculateValue, dependencies);
  • 引数:

calculateValue キャッシュする値を計算する関数
純粋で、引数を取らず、任意の型の値を返す必要があります。 React は、最初のレンダリング中に関数を呼び出します。

dependencies 依存関係
fn コード内で参照されるすべてのリアクティブ値のリスト。リアクティブ値には、props、state、およびコンポーネント本体内で直接宣言されたすべての変数と関数が含まれます。

  • 返り値:

最初のレンダリングで、useMemo は、引数なしで calculateValue を呼び出した結果を返します。
次のレンダリング中に、(依存関係が変更されていない場合) 最後のレンダリングから既に格納されている値を返すか、calculateValue を再度呼び出して、calculateValue が返した結果を返します。

いつ使うのか

どちらも不要なレンダリングを防ぎたい時に、使います。
パフォーマンスの最適化としてのみ useMemo,useCallback を使う必要があります。
これがないとコードが機能しない場合は、根本的な問題を見つけて、最初に修正してください。

GitHubで編集を提案

Discussion