💡

【react】setstateで更新がブラウザ表示と1つずれる問題

2023/04/08に公開

問題の概要

1つの関数内で、setstateでstateを更新した際に、
その値をその関数内で使用したい場合には更新前の値が取得され、
ブラウザで表示させる値は更新後が表示される。

具体例

数字をstateで管理し、setstateで1足した値をconsole.logで表示する関数

    const [num, setNum] = useState(0)

    function increment() {
        setNum((num) => num++);
        console.log(num);
    }

更新後の値が取得できない原因

原因はsetstate関数が非同期処理というところにあります。
そのため、関数の処理の流れが変わってしまいます。

increment()を実行した時の処理の流れ

  1. setNumが呼ばれる(非同期なので処理が完了する前に後述の処理に行く)
  2. console.log(num)が呼ばれる
  3. setNumの処理が完了する
  4. レンダリングが行われる(stateの更新がされたため)

となるので、console.log(num)が呼ばれるときにまだsetNumの処理が完了していないため、
更新前の値が取得されてしまう。

解決策

同一の関数内でsetstateで更新した後の値を使いたければ、
更新後の値をまず定義して、setstateでも、console.log()でもそれを使うという方法を取ります。

    const [num, setNum] = useState(0)

    function increment() {
        const new_num = num + 1;
        setNum((num) => new_num);
        console.log(new_num);
    }

Discussion