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

React hooksを理解する(useCallback)

Posted at

目次

1.useCallbackとは?
2.useCallbackの基本的な使い方
3.useCallbackを使うメリット
4.useCallbackの実践例
5.useCallbackの注意点
6.useCallbackとuseMemoの違い
7.useCallbackとReact.memoの違い
8.まとめ

useCallbackとは?

useCallbackは、Reactでメモ化したコールバック関数を作成するためのフック です。

通常、React ではコンポーネントが再レンダリングされるたびに関数が再生成されるという仕様があります。これは問題になることは少ないですが、以下のような場合に不要なレンダリングや処理の無駄を防ぐためにuseCallbackが役立ちます。

useCallback が必要なケース

  • 関数をメモ化して、無駄な再生成を防ぐ
  • 子コンポーネントに渡す関数が再生成されることを防ぎ、不要な再レンダリングを抑える
  • パフォーマンスを最適化するための最適化(React.memo と組み合わせる)

useCallback の基本的な使い方

インポート方法

useCallbackはReactのフックなので、reactからインポートします。


import React, { useCallback } from 'react';

基本構文


const memoizedFunction = useCallBack(() => {
    // 関数の処理
}, [依存する値]);

:pencil2: 解説

  • useCallbackは第1引数に関数を取り、第2引数に依存配列を指定します。
  • 依存配列の値が変わらない限り、関数は再生成されません。

シンプルな例

通常の関数では、コンポーネントが再レンダリングされるたびに関数が新しく作成されます。


function Example() {
  const handleClick = () => {
    console.log("ボタンがクリックされました");
  };

  return <button onClick={handleClick}>クリック</button>;
}

しかし、useCallback を使うと 関数のメモ化(再利用) が可能になります。


import React, { useCallback } from "react";

function Example() {
  const handleClick = useCallback(() => {
    console.log("ボタンがクリックされました");
  }, []);

  return <button onClick={handleClick}>クリック</button>;
}

:pencil2: 解説

  • handleClickは最初のレンダリング時に一度だけ作成され、それ以降は再利用される。
  • 依存配列 [] を空にすると、コンポーネントが再レンダリングされても関数は再生成されない。

useCallbackを使うメリット

1.子コンポーネントの不要な再レンダリングを防ぐ

  • useCallback を使わない場合、親コンポーネントが再レンダリングされると、子コンポーネントに渡す関数も毎回新しく作られてしまい、子コンポーネントが無駄に再レンダリングされる 可能性があります。
2. パフォーマンスの最適化
  • 再生成を避けることで、処理のオーバーヘッドを削減 できる。
  • 特にReact.memoと組み合わせると、最適化の効果が高まる。

useCallbackの実践例

子コンポーネントの再レンダリングを抑える

useCallbackを使わないと、親コンポーネントが再レンダリングされるたびに子コンポーネントに渡す関数が新しくなり、子コンポーネントが不要に再レンダリングされてしまいます。


import React, { useState } from 'react';

function child({ handleClick }) {
    console.log("Child コンポーネントがレンダリングされました。");
    return <button onClick={handleClick}>クリック</button>;
}

function Parent() {
    const [count, setCount] = useState(0);

    // 毎回新しい関数が作られる
    const handleClick = () => {
        console.log("ボタンがクリックされました。");
    };

    return (
        <div>
            <p>カウント: {count}</p>
            <button onClick={() => setCount(count +1)}>カウントアップ</button>
            <Child handelClick={handleClick} />
        </div>
    );
}

export default Parent;

:pencil2: 解説

  • Parentが再レンダリングされるたびにhandleClickが再生成され、Childが不要にレンダリングされる。

解決策(useCallbackを使用)


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

function Child({ handleClick }) {
  console.log("Child コンポーネントがレンダリングされました");
  return <button onClick={handleClick}>クリック</button>;
}

const MemoizedChild = React.memo(Child);

function Parent() {
  const [count, setCount] = useState(0);

  // useCallback を使用して関数をメモ化
  const handleClick = useCallback(() => {
    console.log("ボタンがクリックされました");
  }, []);

  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>カウントアップ</button>
      <MemoizedChild handleClick={handleClick} />
    </div>
  );
}

export default Parent;


:pencil2: 解説

  • handleClickがメモ化され、Parentが再レンダリングされてもChildが無駄に再レンダリングされない!
  • React.memoを使うことでChildの再レンダリングを防止。

useCallback の注意点

1.むやみに使うと逆効果

  • 使いすぎるとメモリを消費するため、最適化どころかパフォーマンスが悪化する可能性がある。
  • 必要な場面だけに適用する(子コンポーネントの React.memo との組み合わせが有効)。

2.依存配列を適切に設定する

  • 依存配列が適切でないと、古い状態を参照してしまい、意図しない動作をすることがある。

useCallbackuseMemoの違い

useCallback useMemo
目的 関数をメモ化する 計算結果をメモ化する
戻り値 メモ化された関数 メモ化された値
使いどころ コールバック関数の再生成を防ぐ 計算コストの高い値をキャッシュする
const memoizedFn = useCallback(() => {}, [deps]); const memoizedValue = useMemo(() => computeValue(), [deps]);

useCallbackReact.memoの違い

useCallback React.memo
目的 関数をメモ化する コンポーネントをメモ化する
戻り値 メモ化された関数 メモ化されたコンポーネント
使いどころ コールバック関数の再生成を防ぐ コンポーネントの再レンダリングを抑え、不要な描画を防ぐ
const memoizedFn = useCallback(() => {}, [deps]); const MemoizedComponent = React.memo(Component);

まとめ

  • useCallbackは関数をメモ化し、再レンダリング時の無駄な関数再生成を防ぐ。
  • 子コンポーネントの再レンダリングを抑える のに役立つ。
  • React.memoと組み合わせると効果的。
  • 適切な場面で使わないと逆効果になることもある。
  • useMemo は値のメモ化、useCallbackは関数のメモ化をする点が違う。
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?