react-hooks/exhaustive-deps
ESLint の eslint-plugin-react-hooks プラグインのルールの 1 つ 場合によっては省略することが妥当な場合もある
本当か? radish-miyazaki.icon
e.g. useEffect をマウント時のみ実行したいケース
初期 Props を使って何かしらの初期化を行うなど この場合、useEffect の第 2 引数は [] になる
しかし、依存関係を省略することはバグの原因となる
そのため、react-hooks/exhaustive-deps は有効にし、どうしても必要な場合は以下のようにしてルールを上書きするのが良い
code:tsx
// eslint-disable-next-line react-hooks/exhaustive-deps
なぜ省略する必要があるのか、必ず理由を記述すること
react-hooks/exhaustive-deps のエラーは 0 にすべき(ルールは上書きしない)という意見もある radish-miyazaki.icon
このルールはReactの最も基本的なルールの一つであり、オフにしないとコードを書けないケースはプロダクトコードを書くうえで、基本的に存在しません。
オフにすると以下のような問題が発生する
変更時に含めるべき依存関係を入れ忘れ、値の変更が反映されない
非同期で更新される props 更新の順序が変わると壊れるなどの 競合状態 の発生 ルールをオンにしている限り発生しない問題でバグが発生した場合、特定のレンダリングの順序のみで不具合が発生することになり、原因の特定が非常に難しくなります
2. Reactのバージョンアップ時などに困る問題
React の基本的な前提として、何度余分に render しても壊れないコードを書く必要があります
deps を空にして [] を指定して一度しか走らせないようにしているコードは堅牢でなく、render 回数に依存したコードとなっており React の semantics に違反しています
関連して、一度しか effect を走らせないため subscribe 後の cleanup の関数が不要に感じられたとしても、基本的に必ず cleanup は書く必要があります
一度しか走らないことを意図したコードでも、開発中に React の Fast Refresh 時に Component が再レンダリングされるケースが存在します
cleanup のコード を書かないと subscribe などの関数が多重に登録されて開発がしづらくなります
どう回避すんの?
code:tsx
const onVisit = useEffectEvent(visitedUrl => {
logVisit(visitedUrl, numberOfItems);
});
useEffect(() => {
onVisit(url);