Next.js

warning「React Hook useEffect has a missing dependency」の原因と対処法

はじめに

コンポーネントがマウントされた時に特定の条件下でステートを変えるだけのシンプルな処理を作成中に表題のwarningが発生…
ビルドできるし問題ないんだけど、気持ち悪いので調べた原因と対処法をメモ…

該当コード

const [isShow, setIsShow] = useState(true);
useEffect(() => {
    if (totalCount / PER_PAGE <= 1) setIsShow(false);
}, []);

Warning

Warning: React Hook useEffect has missing dependencies: 'PER_PAGE' and 'totalCount'. Either include them or remove the dependency array.  react-hooks/exhaustive-deps

warningの原因

useEffect内で依存関係を引き起こす変数を使用しており、かつuseEffectの第二引数に空配列を指定した場合、このwarningが発生する(useEffectは、第二引数に指定されたステートの変更を検知してuseEffect内の関数を実行するという動作をするため)

今回はマウント時に一回だけ実行できれば良いので、第二引数に空配列を指定したのが原因みたい

warningを解消方法

解消方法は大きく分けると二つ

  • 依存関係を解消する
  • ESLintのルールを無効にする

依存関係を解消する

const [isShow, setIsShow] = useState(true);
useEffect(() => {
    if (totalCount / PER_PAGE <= 1) setIsShow(false);
}, [totalCount,PER_PAGE]);

シンプルに第二引数を指定して依存関係を解消してあげる方法。
これだとtotalCountPER_PAGEが更新されるたびにuseEffectが実行されてしまう。
今回はマウント時に一度だけ実行したいので、意図している挙動とは違う実装になるのでNG。

ESLintのルールを無効にする

useEffect(() => {
        if (totalCount / PER_PAGE <= 1) setIsShow(false);
        // eslint-disable-next-line
    }, []);

// eslint-disable-next-lineというコメントを記述した直下のコードのルールを無効にできる。
今回の場合、警告を消すならこれが一番良さそうだが、該当箇所に都度コメントを書かないといけないというデメリットもある

おまけ

.eslintrc.jsonrulesを設定すると事で、全体のESLintルールを無効にしてしまうという荒技もある

//.eslintrc.json
{
    "extends": ["next/core-web-vitals", "next/typescript"],
    "rules": {
        "react-hooks/exhaustive-deps": "off" //これを追加
    }
}
ABOUT ME
ytakeuchi
都内在住のフロントエンドエンジニア。2016年からフリーランスとして活動中。座右の銘は「昨日よりも楽に」。好きな言葉は「効率化」。こんな性格なのでプライベートではGoogle Apps Scriptばかり触っています。