useEffect has a missing dependencyのwarningを解消する
こんにちは
マッケイです。
まとめまで書き終わった後に突如ページが消えて、まっさらのページを見ながら、それでもなお不屈の精神で書き上げた記事になります。
はじめに
僕が運営するReact Bootcampというコミュニティにて、useEffect has amissing dependency
というwarning
を解消したいという声を聞きました。
僕自身も体系だった情報がないかと探したところ、見当たらなかったのでこの記事を執筆しました。
warning
が発生する?
なぜそもそもなぜこのwarning
が発生しているのでしょうか?
このwarning
を出している本体は、ESLintです。
ESLintが、useEffect
関数に対して「依存関係おかしいでお前」と注意を出してくれています。
このwarning
が出るタイミングは以下のような関数を書いた時です。
useEffect(()=>{
something(dependency, otherDependency);
},[]);
useEffect
内で依存関係を引き起こす変数(概ねuseStateの変数)を使用しており、かつuseEffect
の第二引数に空配列を指定した場合、このwarning
が発生します。
useEffect
は、第二引数に指定されたステートの変更を検知して、useEffect
内の関数を実行するという動作をします。
その中で、依存関係を指定しないまま関数を記述していると丁寧にESLintが「依存関係を解決してないで」と注意をくれます。
とは言っても、コンポーネントがマウントされた時に一回だけ使用したいというユースケースもあります。
そんなとき、このwarning
は少しうるさいですね。
warning
を解消する
ではこのwarning
を解消する方法を見ていきます。
warning
の解消には、3つの方法があります。
- 依存関係を解消する
- 特定の行だけESLintのルールを無効にする
- コード全体でESLintのルールを無効にする
依存関係を解消する
当然ながら、注意を受けている依存関係を全て解消すればwaning
は消えます。
useEffect(()=>{
something(dependency, otherDependency);
},[dependency, otherDependency]);
しかし、これではdependency
やotherDependency
が更新されるたびにuseEffect
が実行されます。
今回のユースケースでは使えません。
特定の行だけESLintのルールを無効にする
そこで、ESLintのルールを部分的に無効にすることで、この問題を解決できます。
useEffect(()=>{
something(dependency, otherDependency);
// eslint-disable-next-line react-hooks/exhaustive-deps
},[]);
// eslint-disable-next-line react-hooks/exhaustive-deps
というコメントを記述した直下のコードは、warning
を出しているコードのルールを無効にできます。
見てわかる通り、このwarning
はreact-hooks/exhaustive-deps
というESLintのルールで吐き出されています。
よって、そのルールを無効にすることでwarning
を止めることができます。
しかし、この方法では必要な全ての箇所でコメントを記述しなければならず、なかなかに骨の折れる作業です。
コード全体でESLintのルールを無効にする
それならばコード全体でそのルールを無効にしてしまえばいいのではないかということで、ESLintのルールを書き変えて、warning
をコード全体から排除します。
普通であれば、ESintが有効な場合、ルートディレクトリに.eslintrc
なりeslint.json
なりのESLintのconfigファイルが生成されています。
しかし、create-react-app
で作成されたプロジェクトではこのconfigファイルがありません。
にも関わらず、ESLintが有効になっているのがcreate-react-app
のややこしいところです。
create-react-app
では、ESLintの設定がpackage.json
に記述されます。
そのため、ESLintのルールを書き換えるときは、package.json
のESLintの記述を変更する必要があります。
{
...
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
],
// NEW!!!!
"rules": {
"react-hooks/exhaustive-deps": "off"
}
},
...
}
eslintConfig
という項目に対して、rules
を新規に追加しています。
これで、コードベース全体でuseEffect has amissing dependency
のwarning
を解消できます。
また、package.json
にESLintの設定を書くのが気持ち悪いという方は、.eslintrc
をルートディレクトリに作成し、ESLintのルールをそこに書くこともできます。
{
"extends": ["react-app", "react-app/jest"],
"rules": {
"react-hooks/exhaustive-deps": "off"
}
}
もちろんpackage.json
から、eslintConfig
を消すことをお忘れなく。
まとめ
useEffect has amissing dependencyのwarningを解消する方法をご紹介しました。
ESLintは便利な反面おせっかいなところも見え隠れします。
特に自動生成される系のルールは知らない間にたくさんのルールが設定されているので、これを機にどのようなルールが設定されているかを見てみるのも面白いかもしれません。
Discussion