🍣
useEffect内での不要なstate更新を避ける
最初に
Reactの公式ドキュメントを読んでいて、誤ったuseEffectの使い方をしていることを学んだので、記録します。
前提
Reactは、stateを更新するとコンポーネントを再レンダリングした後に、useEffectを実行する。
そのため、useEffectでstateを更新してしまうと、せっかくstateを更新した後に再度useEffectでも更新されてしまい、パフォーマンスが低下してしまう上に思わぬ不具合につながる。
なので、既存のpropsやstateから計算できるものはstateに入れず、レンダー中に計算するべき。
よくない例
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
// ...
}
この処理の流れは以下
- firstName, lastNameのstateが更新される
- 新しいfirstName, lastNameの値でコンポーネントが再レンダリングされる。この時点でfullNameは古いまま(fullNameを書き換えるコードはuseEffect内にしかないが、まだuseEffectは実行されていないため)
- useEffectが実行され、fullNameのstateが更新される。これにより新しいfullNameの値で再レンダリングされる
- firstName, lastNameが更新されていないのでuseEffectは実行されない
2回レンダリングされてしまっている。なので以下のようにする
いい例
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
const fullName = firstName + ' ' + lastName;
// ...
}
こうすれば処理の流れが以下になる
- firstName, lastNameのstateが更新される
- 新しいfirstName, lastNameの値でコンポーネントが再レンダリングされる。その時にfullNameも新しい値になる
レンダリング回数が1回だけになり、無駄がなくなりました!
最後に
他にもよく無い使い方をしてしまっている(確信)ので、正しい使い方を学んでいきます!
Discussion