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

React useState重渲染后取值异常:秒表组件迁移故障排查

秒表组件迁移后状态不同步问题

我正在仪表盘上开发一款秒表应用,需实现将秒表(计时数据)从一个组件迁移到另一个组件的功能。父组件通过props向Stopwatch子组件传递getTables函数,该函数会调用API并通过state触发重渲染。

父组件相关代码

获取表格数据函数

const getTables = async () => {
    try {
      const res = await fetchTables();

      setTables(res.data.data.table);
    } catch (error: any) {
      toast.error(error?.error.message);
    }
  };

渲染Stopwatch子组件

{tables.map((e: Table) => {
          return (
            <Stopwatch
              key={e?.id}
              table={e}
              getTables={getTables}
              tables={tables}
            />
          );
        })}

重渲染正常触发,API功能正常,刷新页面后也能正常工作。

子组件相关代码

状态初始化与时间计算

const Stopwatch = ({ table, getTables, tables }: Props) => {
  const stoppedTime: Timestamp = {
    hours: table.active_stopwatch[0]?.hours,
    minutes: table.active_stopwatch[0]?.minutes,
    seconds: table.active_stopwatch[0]?.seconds,
  };
  const time: Timestamp =
    table.active_stopwatch[0]?.status == "paused"
      ? stoppedTime
      : seperateDate(
          table.active_stopwatch[0]?.updated_at || new Date(),
          stoppedTime
        );

  console.log(time, table.id, table.active_stopwatch); // time能得到正确的时/分/秒
  const [seconds, setSeconds] = useState(time.seconds || 0); //这些状态无法同步time中的值
  const [minutes, setMinutes] = useState(time.minutes || 0);
  const [hours, setHours] = useState(time.hours || 0);
...

迁移秒表的处理函数

const handleMoveTable = async (id: number) => {
    const confirmed = window.confirm("Are you sure?");

    const payload = {
      table_id: id,
      hours: hours,
      minutes: minutes,
      seconds: seconds,
    };
    if (confirmed) {
      try {
        if (table.active_stopwatch[0] !== undefined) {
          await moveStopwatch(table.active_stopwatch[0].id, payload);
          getTables();
        } else {
          throw new Error("Stopwatch is not active");
        }
        toast.success("Success");
      } catch (error: any) {
        toast.error("There was an error moving the stopwatch");
      }
    }
  };

问题详情

我尝试用useEffect设置状态,但结果相同。我直接显示状态中的值,尝试用time常量显示存在Bug,并非预期方案。window.reload可以解决问题,但我不想刷新页面。是否有遗漏的点?如有需要我可以提供更多信息。

编辑补充:日志验证问题

添加console.log后,能更清晰看到问题:

const time: Timestamp =
    table.active_stopwatch[0]?.status == "paused"
      ? stoppedTime
      : seperateDate(
          table.active_stopwatch[0]?.updated_at || new Date(),
          stoppedTime
        );

  const [seconds, setSeconds] = useState(time.seconds || 0);
  const [minutes, setMinutes] = useState(time.minutes || 0);
  const [hours, setHours] = useState(time.hours || 0);
  console.log(
    "const time seconds = " + time.seconds,
    "stateSeconds = " + seconds,
    "table_id " + table.id
  );

从日志可以看到,迁移前seconds与time.seconds值一致,迁移后time.seconds更新但state中的seconds未变化,行为异常。


内容的提问来源于stack exchange,提问作者Reklyss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:35:01