React v19:useTransition hook 与 <Activity />
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 的机制。