初回レンダリング時にuseEffectを実行しないようにする方法
はじめに
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 (
// ここにコンポーネントのレンダリング内容を記述します。
);
}
上記のコードでは、useRef
でisFirstRender
という参照を作成し、初回レンダリング時にtrue
を保持しています。useEffect
内でisFirstRender.current
がtrue
の場合、処理をスキップし、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