DEVDEV

useStateの罠

作成日
2022-04-14
更新日
2022-04-22

※配列の変更を見れてない可能性あり

問題

React は再レンダー間で setState 関数の同一性が保たれ、変化しないことを保証します。従って useEffect や useCallback の依存リストにはこの関数を含めないでも構いません

レンダリングが完了する間に、複数回stateを変更したとしても、一番最後に指定した値が適用される。

この問題は、 Class ComponentのsetStateでは発生しないが、useState Hookでは発生する。

問題のコード

大体こんな感じ

tsx
const [items, setItems] = useState<string[]>([]) const handleSubmit = (text: string) => { append(text) send(text) } const append = (text: string) => { setItems([...items, text]) } const send = (text: string) => { client.post('/api/post') .then(res => { append(res.data) }) }

Code Sandbox

解決策

関数型のsetStateを使用する。

クラスコンポーネントの setState メソッドとは異なり、useState は自動的な更新オブジェクトのマージを行いません。この動作は関数型の更新形式をスプレッド構文と併用することで再現可能です:

Code Sandbox

また、createRefとuseRefでも高い現象が起こるので、注意。 クラスコンポーネントと関数コンポーネントで、挙動が異なる

参考

Related

TAGS

ReactJS

SHARE