🚀

未解決:useStateの値が非同期では更新されない?

2023/12/21に公開

やりたかったこと

1秒ごとにloadingの値を1増やしたい

コード

import React, { useEffect, useState } from "react";
import Loading from "./Loading";

function LongSleep() {
  const [loading, setLoading] = useState(0);
  const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
  
  const dummyQuery = (_loading) => {
    setLoading(_loading+1);
    console.log(loading);
  }

  const intervalRepeater = async (callback, interval) => {
    console.log("処理開始")
    while (loading<100) {
      const starttime = new Date().toString();
      await Promise.all([callback(loading), sleep(interval)])
      console.log(loading);
    }
    console.log("処理終了");
  }
  
  useEffect(() => {
    intervalRepeater(dummyQuery, 1000);
  }, [])

  return (
    <>
      <div>{loading?.toString()}</div>
    </>
  )
}

export default LongSleep;

結果


画面上に表示されるのはloadingの値は1、にもかかわらずconsoleでは0のまま。

予想される原因

while内で使用されるloadingの値は常に初期値が用いられている?
また画面上ではloadingの値が更新されていないのでそもそも画面に変更がない?
またuseEffectの[]にloadingをいれたところマイフレームごとに更新されてしまった

解決のヒント?

参考記事:https://cpoint-lab.co.jp/article/202111/21316/
intervaRepeaterに渡されるloadingとsetStateで使用される変数は異なるものとして扱われる?

Discussion