[React 18] useEffect 2実行しまう問題対処

2 min read

React 18 から、厳密モードが有効になっている開発モードでのみ useEffect が 2 回実行されるようになった。

確認した環境

現象を確認したのは以下の環境。

  • next: v12.2.2
  • react: v18.2.0
  • react-dom: v18.2.0

解決方法

状況に応じて、以下のいずれかで対応が可能。

StrictModeコンポーネントを削除する

厳密モードでなくすることで防ぐ。

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  // <StrictMode>
  <App />
  // </StrictMode>
);

クリーンアップ関数を定義する

クリーンアップ関数を定義して複数回実行されても問題ないようにする。

const [results, setResults] = useState([]);
const [page, setPage] = useState(1);

useEffect(() => {
  let ignore = false;

  fetchResults(query, page).then((json) => {
    if (!ignore) {
      setResults(json);
    }
  });

  return () => {
    ignore = true;
  };
}, [query, page]);

useRefを利用する

useRefで初回は実行しないようにする。

const refFirstRef = useRef(true);

useEffect(() => {
  if (process.env.NODE_ENV === "development") {
    if (refFirstRef.current) {
      refFirstRef.current = false;
      return;
    }
  }

  something();
}, []);

プロダクションビルド時に実行されなくなってしまうため、process.env.NODE_ENV === 'development'の判定を入れて開発モードのみの処理にしておく。

参考

このページをシェアする

関連タグ

関連記事

StorybookでEmotion 11がエラーになる問題の解決方法

状況 / 環境 / 解決方法 / 参考

[Next.js] Google Adsenseを表示させる方法

環境 / 条件 / 方法

CSS in JSとは何か

想定読者 / そもそも JS フレームワーク(React、Vue.js)を採用する理由とは何か / 「命令的 UI」 と 「宣言的 UI」 / 「命令的 UI」 VS 「宣言的 UI」 / CSS in JS とは / CSS in JS ライブラリ / Emotion の使い方 / 利用するメリット / 利用するデメ

[初学者向け] Next.js で開発を始める前に知っておきたいポイントと開発方法

想定読者 / 執筆同時のNext.js / Next.js とは / なぜ、Next.js を使うのか / セットアップ / ファイルベースルーティング / 事前レンダリング(プリレンダリング)とは / 参考

[Next.js] Emotion SWCを有効にする方法

概要 / 方法 / その他