🐈

初回レンダリング時にuseEffectを実行しないようにする方法

2023/03/19に公開

はじめに

ReactのuseEffectは、コンポーネントがレンダリングされるたびに副作用を実行するためのフックです。通常、useEffectは初回レンダリング時にも実行されますが、場合によっては初回レンダリング時に副作用を実行したくないケースもあるかと思います。今回はそういったケースの対象法を紹介します。

useRefを使って初回の処理をスキップする方法

useRefを使って初回レンダリング時の副作用をスキップすることができます。まず、useRefを使って参照を作成し、useEffect内でその参照をチェックして初回レンダリング時の処理を回避できます。

以下にコード例を示します。

import { useEffect, useRef } from 'react';

const ExampleComponent = () => {
  const isFirstRender = useRef(true);

  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false;
      return;
    }
    // ここに初回レンダリング時に実行したくない副作用を記述します。
  }, []);

  return (
    // ここにコンポーネントのレンダリング内容を記述します。
  );
}

上記のコードでは、useRefisFirstRenderという参照を作成し、初回レンダリング時にtrueを保持しています。useEffect内でisFirstRender.currenttrueの場合、処理をスキップし、falseに変更します。これにより、初回レンダリング時の副作用を回避できます。

useStateではなくuseRefを使う理由は、useRefがコンポーネントのレンダリングとは無関係にデータを保持できるためです。useRefは、その値が変更されてもコンポーネントの再レンダリングが発生しないため、初回レンダリングの判断に適しています。一方で、useStateを使うと、値が変更されるたびにコンポーネントが再レンダリングされます。このため、初回レンダリングの判断にuseStateを使うと、無駄な再レンダリングが発生してしまいます。

カスタムフックにして便利に使う

この方法をカスタムフックにすることで、さらに便利に使えるようになります。以下にカスタムフックの例を示します。

import { useEffect, useRef, DependencyList } from 'react';

export const useUpdateEffect = (callback: () => void, dependencies: DependencyList) => {
  const isFirstRender = useRef(true);

  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false;
      return;
    }

    return callback();

  }, dependencies);
}

カスタムフックuseUpdateEffectは、useEffectと同様に副作用を実行できますが、初回レンダリング時には実行されません。これを利用して、コンポーネントで簡単に初回レンダリング時の副作用を回避できます。

以下に、カスタムフックを使ったコンポーネントの例を示します。

import { useState } from 'react';
import { useUpdateEffect } from './useUpdateEffect';

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

  useUpdateEffect(() => {
    console.log('カウントが更新されました:', count);
  }, [count]);

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

このように、useUpdateEffectカスタムフックをインポートして使用することで、初回レンダリング時に副作用を実行したくない場合にも対応できます。

まとめ

本記事では、Reactで初回レンダリング時にuseEffect内の処理をスキップする方法として、useRefを用いた方法を紹介しました。またカスタムフックを使って、この機能を汎用的かつ簡単に利用できるようにしました。

ただし、この方法を活用する際には、以下の点について留意していただくことをお勧めします。

  • 初回レンダリング時に副作用をスキップすることが本当に適切なのかどうか慎重に検討する。通常、適切に設計された副作用は初回レンダリング時にも実行されるべきです。

  • 副作用をスキップすることが必要な場合、それがアプリケーションの特殊な要件に基づいていることを確認し、適切な実装方法を選んでください。

  • 初回レンダリング時に副作用をスキップすることが適切でない場合、コンポーネントやアプリケーションの設計を見直すことを検討してみてください。他のフック(useStateやuseReducerなど)を利用して、状態変更に応じた処理を実行することもできます。

読んでいただきありがとうございました!

Discussion