1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

useMemoとReact.memo と useCallback の違いと使い方

Last updated at Posted at 2025-01-12
  • useMemo: 計算結果をメモ化するために使用。重い計算を最適化。
  • React.memo: コンポーネントのレンダリングを最適化。propsが変わらない限り再レンダリングを防ぐ。
  • useCallback: 関数をメモ化するために使用。依存配列の変更がない限り、同じ関数参照を再利用。

1. useMemo

useMemoは、計算コストの高い値をメモ化するために使用されます。依存配列に指定した値が変更されない限り、前回の計算結果を再利用します。

import React, { useMemo, useState } from 'react';

const ExpensiveComponent = ({ num }) => {
  const expensiveValue = useMemo(() => {
    console.log('計算中...');
    return num * 2; // 高コストな計算
  }, [num]);

  return <div>計算結果: {expensiveValue}</div>;
};

const App = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>カウント: {count}</button>
      <ExpensiveComponent num={count} />
    </div>
  );
};

2. React.memo

React.memoは、コンポーネントのレンダリングを最適化するために使用されます。親コンポーネントが再レンダリングされても、propsが変更されない限り、子コンポーネントは再レンダリングされません。

import React, { useState } from 'react';

const ChildComponent = React.memo(({ count }) => {
  console.log('ChildComponentがレンダリングされました');
  return <div>カウント: {count}</div>;
});

const App = () => {
  const [count, setCount] = useState(0);
  const [otherState, setOtherState] = useState(0);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>カウント: {count}</button>
      <button onClick={() => setOtherState(otherState + 1)}>他の状態: {otherState}</button>
      <ChildComponent count={count} />
    </div>
  );
};

3. useCallback

useCallbackは、関数をメモ化するために使用されます。依存配列に指定した値が変更されない限り、前回の関数を再利用します。これにより、子コンポーネントに渡す関数が毎回新しい参照を持つことを防ぎ、不要な再レンダリングを避けることができます。

import React, { useCallback, useState } from 'react';

const Button = React.memo(({ onClick }) => {
  console.log('Buttonがレンダリングされました');
  return <button onClick={onClick}>クリック</button>;
});

const App = () => {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <Button onClick={handleClick} />
      <div>カウント: {count}</div>
    </div>
  );
};

4. useMemouseCallbackの似たような実装の例

例えば、数値を2倍にする関数をメモ化する場合、useMemouseCallbackの両方を使って実現することができます。

useMemoを使用した場合

import React, { useMemo, useState } from 'react';

const App = () => {
  const [num, setNum] = useState(0);

  const doubledValue = useMemo(() => {
    console.log('計算中...');
    return num * 2; // 高コストな計算
  }, [num]);

  return (
    <div>
      <button onClick={() => setNum(num + 1)}>数を増やす: {num}</button>
      <div>2倍: {doubledValue}</div>
    </div>
  );
};

useCallbackを使用した場合

import React, { useCallback, useState } from 'react';

const App = () => {
  const [num, setNum] = useState(0);

  const double = useCallback(() => {
    console.log('計算中...');
    return num * 2; // 高コストな計算
  }, [num]);

  const doubledValue = double();

  return (
    <div>
      <button onClick={() => setNum(num + 1)}>数を増やす: {num}</button>
      <div>2倍: {doubledValue}</div>
    </div>
  );
};

違いのポイント

  1. 目的:

    • useMemo: 計算結果をメモ化して、再計算を避けるために使用します。
    • useCallback: 関数の参照をメモ化して、子コンポーネントの不必要な再レンダリングを防ぐために使用します。
  2. 戻り値の性質:

    • useMemoは、計算結果を返します。
    • useCallbackは、関数自体を返します。
  3. 使用シーン:

    • useMemoは、重い計算や複雑なオブジェクトの生成などに使います。
    • useCallbackは、特に子コンポーネントに関数を渡す場合に重要です。
特徴 useMemo useCallback
目的 計算結果のメモ化 関数のメモ化
戻り値 メモ化された値 メモ化された関数
使用シーン 重い計算を行う場合に使用 子コンポーネントに関数を渡す場合に使用
依存配列 依存する値が変更されると再計算 依存する値が変更されると新しい関数を生成

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?