はじめに
コンポーネントがマウントされた時に特定の条件下でステートを変えるだけのシンプルな処理を作成中に表題の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]);
シンプルに第二引数を指定して依存関係を解消してあげる方法。
これだとtotalCount
やPER_PAGE
が更新されるたびにuseEffect
が実行されてしまう。
今回はマウント時に一度だけ実行したいので、意図している挙動とは違う実装になるのでNG。
ESLintのルールを無効にする
useEffect(() => {
if (totalCount / PER_PAGE <= 1) setIsShow(false);
// eslint-disable-next-line
}, []);
// eslint-disable-next-line
というコメントを記述した直下のコードのルールを無効にできる。
今回の場合、警告を消すならこれが一番良さそうだが、該当箇所に都度コメントを書かないといけないというデメリットもある
おまけ
.eslintrc.json
でrules
を設定すると事で、全体のESLintルールを無効にしてしまうという荒技もある
//.eslintrc.json
{
"extends": ["next/core-web-vitals", "next/typescript"],
"rules": {
"react-hooks/exhaustive-deps": "off" //これを追加
}
}