516 文字
3 分

なぜreact-hooks/exhaustive-depsはただcomponentDidMountのように使いたいだけなのに依存関係を入れてくるのか

2019-04-24
export const Example = ({ loadOnlyOnce }) => {
useEffect(() => {
loadOnlyOnce();
}, [loadOnlyOnce]); // ← WHY?
};

componentDidMount/componentDidUpdate は本来一つのフロー#

クラスコンポーネント時代の React における componentDidMount などのライフサイクルメソッドの最大の問題点は、それを独立したメソッドと捉えさせてしまうこと。実際にはフローの一部であり、 componentDidMount の中で何かを参照する場合、本来同様に componentDidUpdate の中でそれを処理する必要がありる。そうしなければコンポーネントはバグを持つ可能性がある。 これはreact-hooks/exhaustive-depsが修正しようとしているものであり、時間をかけて値を処理するように促している。

次のようなフローを考える。

  1. Component がマウントしたら、prop と何かをする。
    • ロジックを  componentDidMount  または  useEffect  の body に配置する。
  2. Component が更新されたら (prop の値(参照)が変更されたら), 新しい prop と何かをする。
    • ロジックを componentDidUpdate または useEffect の deps に配置する。

react-hooks/exhaustive-depsはこのフローの 2 をやっていないと注意している。

実際のところ、useEffect 自体がこのフローと発生しうるバグに対して立ち向かうことを強いるように設計されている。

自分が思っているだけでは相手に伝わらない#

その処理が確実に一度しか行われないと分かる名前でもない限り、それが本当に一度しか行われないのか、依存関係が本当に不変なのか、他の人がすぐに理解することは出来ません。そして、このルールや React、javascript は他人よりもっと分からずやです。

空の配列を提供することは、「自分のしていることはわかっている」と言っているのと変わらない。

そして何より実際に依存関係が決して変わらないのであれば、含めても問題はない。

なぜreact-hooks/exhaustive-depsはただcomponentDidMountのように使いたいだけなのに依存関係を入れてくるのか
https://blog.ohirunewani.com/posts/react-hooks-exhaustive-deps-why-require-dependencies/
作者
hrdtbs
公開日
2019-04-24
ライセンス
CC BY-NC-SA 4.0