React useEffect useState 只在迭代中重新渲染一些变量

React useEffect useState only re-rendering some variables in iteration

我在模拟打开一包纸牌的场景。我有一个 UI 显示用户拥有的包数量。如果用户有很多包,我有一个功能可以重复快速打开所有包。如果用户选择 'open all',则用户可以看到包的内容 1100 毫秒,直到呈现下一个打开的包。否则他们将不得不单独打开所有包装,这可能很耗时。

每次打开包后,我将 UI 的状态设置为显示包的内容和用户拥有的包数量。包的内容每次都会呈现,但是计数器不会。计数器在最后更新。我很好奇为什么数据每次迭代都会更新,而计数器却不会。

我切换 openAllMode:

  function openAll() {
    setOpenAllMode(!openAllMode);
  }

那我用效果:

  useEffect(() => {
    if (openAllMode) {
      Promise.all(getDataAsPromises()).then(() =>
        setTimeout(() => getUserPackCount(), 1100)
      );
    }
  }, [openAllMode]);

  function getDataAsPromises() {
    return Array(packCount)
      .fill(null)
      .map((c, i) =>
        new Promise((resolve) => setTimeout(resolve, i * 1100)).then(() =>
          getData()
        )
      );
  }

  function getData() {
    getRandomData(1)
      .then((data) => {
          setData(data);
          setPackCount(packCount - 1);
      })
      .then(
        () => {
          console.log("Opened Pack!");
          setOpen(true);
        },
        (error) => {
          console.error("Error Opening Pack: " + error);
          setOpen(false);
        }
      );
  }

基本上每隔1100ms,'setData'的状态就是重新渲染一次。但是,'setPackCount' 的状态直到结束才重新呈现。

您在 packCount 状态上有一个陈旧的外壳。问题是 packCountgetDataAsPromises 回调范围内关闭,每个 setPackCount(packCount - 1); 只是覆盖循环内的先前状态更新。

使用功能状态更新来正确引用任何以前的状态。

setPackCount(packCount => packCount - 1);