[React 18] useEffect が2回実行されてしまう問題の対処法
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'
の判定を入れて開発モードのみの処理にしておく。