You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useEffect内状态数组元素添加过快问题排查与解决

问题:React状态更新时批量添加数组元素而非间隔300ms逐个添加?

我想实现每隔300ms向boolean数组里添加一个true值,但第一个值添加后,后续的第二、第三个值会立刻被一同添加进去。以下是问题代码:

//imports
export default function Card(){

  const [show, setShow] = useState<boolean[]>([]);
  useEffect(() => {
    async function showSections() {
      if (show.length === renderRoutine.sections.length) return;

      console.log("SHOW LENGTH: ", show.length, "ROUTINE LENGTH: ", renderRoutine.sections.length);

      const delay = show.length > 0 ? 300 : 0;
      await timer(delay); // wait if not first
      setShow((show) => [...show, true]);
    }

    showSections();
  }, [show]);

  return (
    {renderRoutine.sections.map(
      (section, idx) => (
        console.log("SHOW IDX", idx + ":", show[idx]),
        console.log("SHOW ARRAY: ", show),
        (
          <Transition
            key={section.name}
            as={Fragment}
            appear={true}
            show={show[idx] === undefined ? false : show[idx]}
            enter="transition ease-in duration-150"
            enterFrom="transform opacity-0 scale-100 -translate-x-3"
            enterTo="transform opacity-100 scale-100"
            leave="transition ease-out duration-75"
            leaveFrom="transform opacity-100 scale-100"
            leaveTo="transform opacity-0 scale-100 translate-x-2"
          >
            //Card elements
          </Transition>
        )
      )}
  );
}

我录制了屏幕录像,能看到useState数组直接被填充了5个boolean值,这一现象该如何解释?


编辑1:根据Ori Drori的答案更新useEffect后

控制台截图显示:多次打印的SHOW LENGTH从0快速递增到5,和ROUTINE LENGTH的数值对应;屏幕录像可见数组元素几乎瞬间被全部添加,完全没有预期的300ms间隔延迟。


编辑2:最终解决方案

给第一个值的添加逻辑单独做判断,修改后的代码如下:

const [show, setShow] = useState<boolean[]>([]);
useEffect(() => {
  async function showSections() {
    if (show.length > renderRoutine.sections.length) return;

    console.log("SHOW LENGTH: ", show.length, "ROUTINE LENGTH: ", renderRoutine.sections.length);

    const delay = show.length > 0 ? 100 : 0;
    await timer(delay); // wait if not first
    if (show.length === 0) {
      setShow([true]);
    } else setShow((show) => [...show, true]);

    console.log(show);
  }

  showSections();
}, [show]);

内容的提问来源于stack exchange,提问作者Furkan Öztürk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:25:59