useEffect
毎回のrendering後に実行される
ただし、第2引数の指定の仕方によって実行をスキップできる
第二引数を指定した場合
rendering後にその値が前回から変化していたら実行される
renderingがトリガーなのであって、useEffect自体にはトリガーの機能はない
「[..]の値が変更されたら実行」ではないことに注意
配列の中に複数設定した場合、どれかが以前から変更されていれば実行される
空配列を指定した場合
mount時とunmount時のみ発火する
cleanupに書いたものはunmount時
第二引数を何も指定しなかった場合 ([]もなし)
renderingされるたびに実行される
初回とか、stateが変更されたときとか
何も指定していないときと、[]を指定したときは挙動が異なる
useeffect周りのdocs (邦訳)
ここでの正しい質問は「エフェクトを 1 回だけ実行する方法」ではなく「再マウントされても正しく動作するようエフェクトを修正する方法」です。
殆どの場合はcleanupを書くことで解決する
reactはui libraryなので、useEffect内でやる処理はUIのためであるべき、という主張
cleanUp関数は必須!
なのでfetchなど、コアロジックに関するものは別の場所でやるべき
「ui libraryなので」というのはちょっと引っかかるけど全体的にはわかる
custom hook使ったら、hooks内はReactの話だけど結局fetchとかするし
ただ、この表現は問題の切り分けとしての説明としてわかりやすい
setHogeはuseStateが呼び出された1回目のみ変更されるので、結局、「1回目だけでuseEffectを実行して、その後のrendering時は実行しない」という意味になる
どういうとき?
fetchするときとか
初回は実行したくなければ以下のuseDidUpdateEffectを使うと良い ref code:ts
export function useDidUpdateEffect(
fn: EffectCallback,
inputs?: DependencyList
) {
const didMountRef = useRef(false);
useEffect(() => {
if (didMountRef.current) fn();
else didMountRef.current = true;
}, inputs);
}
clean upについて
再描画時のuseEffectが呼ばれる前、もしくはunmount時の処理
useEffectの第一引数の関数のreturnのところに処理を書く
dom更新の前に呼び出される
依存リストをカスタマイズしたい
アプリケーションの初期家事
code:BAD.ts
function App() {
useEffect(() => {
loadDataFromLocalStorage();
checkAuthToken();
}, []);
// ...
}
これは依存する props や state をすべて書くべきというルールですが、これに対して嘘を付きたくなる状況では別の選択肢が優れていたり、依存を減らす手段があります
根拠が薄いが、そうかもな、と思ったmrsekut.icon
fetch時にuseEffectを使う
参考
Dan氏の。長い。
visual guide
公式のbeta docs