React v19:useTransition hook 与 <Activity />

发布: (2026年1月6日 GMT+8 06:37)
3 min read
原文: Dev.to

Source: Dev.to

概览

我在尝试 useTransition Hook(React 文档)时发现,当 UI 组件失去焦点——例如用户在组件渲染、计算或获取大量数据的过程中离开页面——组件的数据不会被保留。这是预期的行为,但有时我们希望数据保持“活跃”,这样用户返回时就不需要再次重新获取或重新计算。

一种解决方案是使用 “ 组件包裹内容,该组件拥有 mode 属性,可设置为 "visible""hidden"React 文档)。默认模式是 "visible",正好满足我们的需求。

关键步骤

1. 使用 useTransition

const [isPending, startTransition] = useTransition();

2. 用延迟模拟一次耗时的获取

const delay = async (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

3. 启动 transition 并获取数据

startTransition(async () => {
  if (key === "profile") {
    await delay(1100);          // 模拟延迟
    await fetchData();          // 替换为真实的 fetch
  }
});

4. 用 “ 包裹获取到的数据

<>
  <TabPanel value="home">
    Tab content for Home
    {data}
  </TabPanel>

  <TabPanel value="contact">
    Tab content for Contact
  </TabPanel>
</>

{isPending ? "Fetching data..." : ""}

结果

即使用户离开(例如切换到其他标签页)后再返回 Profile 标签,获取到的数据仍然保持可见。“ 包装器在组件失去焦点时保留了已渲染的输出。

完整源码已放在仓库中: 。

差距与建议

  • 观察: 当用户返回 Profile 标签时,数据仍然显示,但 isPending 会再次触发,说明 startTransition(进而 handleTabChange)又被执行了一遍。
  • 问题: 是否有办法让 useTransition 与 “ 协同工作,使得在标签页重新进入时不再重新触发 transition,还是这就是 React 对 DOM 的默认处理方式?
  • 潜在改进: 未来的更新可以考虑解决此问题,例如通过缓存 transition 状态,或提供在数据已存在时跳过冗余 transition 的机制。
Back to Blog

相关文章

阅读更多 »