来週あたりからReactをほぼ半年ぶりくらいに書く機会があるので思い出していくためにアウトプットしていきます。
useState
React は再レンダー間で setState 関数の同一性が保たれ、変化しないことを保証します。従って useEffect や useCallback の依存リストにはこの関数を含めないでも構いません。
新しい state が前の state に基づいて計算される場合は、setState に関数を渡すことができます。この関数は前回の state の値を受け取り、更新された値を返します。以下は、setState の両方の形式を用いたカウンタコンポーネントの例です。
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
クロージャっぽい。
stateの値が変わると見た目が変わります。
この場合、 以下のカウントの部分が変わります。
Count: {count}
またこのstateのやっかいなところが更新が非同期なため、
const countUp = () => {
setCount(count + 1)
console.log(count)
}
上記のようにしてもconsole.logで表示されるcountの値はsetConuntされる前の値になります。
最初useStateを使用した時はこの挙動で実装がうまくいかずかなり時間を溶かした思い出があります。
コンポーネントのsetCountで更新したらブラウザ上にも反映されるのが不思議だと感じる人もいるかもしれません。即座に反映されるのはuseStateで変数の値を更新する度にコンポーネントが再実行され、ブラウザ上で変数の再描写が行われているためです。ReactではuseStateによる変数の更新だけではなくpropsが更新されてもコンポーネントの再描写が行われるということを理解しておく必要があります。再描写を行う仕組みがない場合はstateを更新しても最新の情報がブラウザに表示されることはありません。React HooksのuseCallback, useMeme, useRef等がコンポーネントの再描写に関わってきます。
ここら辺の再描画に関しての知識があまりない状態で使っていたので深掘りしていきます。
Reactが再描画されるのは以下のタイミングです。この中にstateが入っています。
- stateが更新された時
- propsが更新された時
- 親コンポーネントが再レンダリングされた時
1と3の合わせ技で親コンポーネントのstateが更新された時に子コンポーネントがレンダリングされてしまいますね。
再レンダリングの制御に関しては以下のサイトがわかりやすいです。
参考サイト