首页 / 文章 / 采用 React 19.2:标签页界面的新功能及升级检查清单

采用 React 19.2:标签页界面的新功能及升级检查清单

React 19.2中的Activity机制如何让隐藏的标签页保持活跃状态,useEffectEvent与预渲染功能各自的作用是什么,以及该如何判断现在是否应该升级并修补RSC应用。

904 词

标签页、向导和屏幕外列表都有一个共同的问题:通过条件渲染隐藏面板时,该面板会被卸载,同时带走的还有滚动位置、未填完的表单以及已获取的数据。React 19.2通过Activity组件解决了这一问题。本指南将把Activity应用于标签页布局,随后会介绍该版本的其余功能以及判断何时升级的检查清单。

19.2试图解决什么问题

React现在每年都会发布多个版本,而19.2并非彻底重写。它针对的是一些长期存在的痛点:组件卸载时状态丢失、效应依赖带来的麻烦,以及快速加载的静态页面与实时更新数据之间的权衡问题。

Activity:在不破坏UI的情况下隐藏它

可以把Activity视为{condition && <Panel />}的更智能替代方案。它接受一个名为mode的属性,该属性有两个取值:

  • hidden 会隐藏子元素,卸载它们的副作用,并将所有更新推迟到 React 没有更高优先级的工作时再处理。
  • visible 会显示子元素,重新加载它们的副作用,并正常处理更新。

关键在于哪些内容会被保留。组件状态和渲染后的树结构会得以保存,因此切换回来是即时的,但在隐藏状态下副作用会被清理。这样一来,订阅、定时器以及轮询都会停止,这通常正是对于没人正在使用的面板所期望的效果。

下面的示例将设置面板和账单面板分别封装在各自的 Activity 结构中,activeTab 属性决定哪个面板可见。当用户切换离开时,两个面板都会保留其滚动位置和表单输入内容。

// Preserve a tab's scroll position and form state
// even when the user switches away from it
import { unstable_Activity as Activity } from 'react';

function ProfileTabs({ activeTab }) {
  return (
    <>
      <Activity mode={activeTab === 'settings' ? 'visible' : 'hidden'}>
        <SettingsPanel />
      </Activity>
      <Activity mode={activeTab === 'billing' ? 'visible' : 'hidden'}>
        <BillingPanel />
      </Activity>
    </>
  );
}

需要注意一点:该代码片段导入了 unstable_Activity,这是预发布版本中使用的名称。在稳定版 19.2 中,该组件被导出为 Activity,因此升级时请查阅最新文档,并使用该名称进行导入。

由于每次切换时都不会拆毁并重新构建任何内容,导航速度因而更快。但代价是内存占用:所有隐藏面板都会保持存活状态,因此建议将 Activity 用于用户可能再次访问的页面,而非为每条路由都创建实例。

useEffectEvent:无需重新运行效应即可获取最新值

如果你曾为了满足代码检查工具的要求而将某个值添加到依赖数组中,结果却导致某些效应在不应触发时反而被执行,那么这个钩子就能解决这个问题。它允许某个效应通过独立的函数来读取最新的属性和状态,而不会因为该值的变化而导致效应重新运行。

此处 theme 是在 onConnected 中读取的,因此连接仅取决于 roomId

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme); // always fresh theme
  });

  useEffect(() => {
    const connection = createConnection(roomId);
    connection.on('connected', () => onConnected());
    return () => connection.disconnect();
  }, [roomId]); // theme intentionally left out — and that's fine now
}

请注意,该代码片段省略了实际实现中在返回清理逻辑之前必须调用的 connection.connect() 方法。

React DOM中的部分预渲染

部分预渲染最初是Next.js 14的一个实验性功能,而在19.2版本中,这一底层能力已成为 react-dom 的一部分。React会提前预渲染页面的静态结构,在动态Suspense边界处留下空白,然后根据每次请求来填充这些空白。这样既能获得接近静态生成的渲染速度,又能保持服务器端渲染的实时性。我们在React 19.2的SSR基础机制、cacheSignal和PPR一文中详细介绍了相关API。

值得了解的次要更新

  • Chrome DevTools新增了针对React的性能追踪功能,可查看React将哪些操作标记为阻塞任务、哪些标记为过渡任务等。
  • React Server Components引入的cacheSignal功能有助于避免因缓存计算而产生的冗余工作。
  • SSR流式处理的改进旨在缩短应用达到交互状态的时间。

安全性:优先修复RSC应用

React Server Components存在严重漏洞,该漏洞于2025年12月被披露。使用RSC的React 19.0.0至19.2.2版本的应用,包括默认的create-next-app配置,都存在远程代码执行风险。如果正在使用Server Components,请立即升级到已修复的版本;具体修复版本请参考React和Next.js的官方公告,因为后续还有补丁发布。

您的团队现在应该升级吗?

  • 如果您正在开发复杂的 SSR 应用、需要构建包含多个标签页或步骤的用户界面,或是不断遇到效果依赖问题,应尽快升级
  • 如果您维护着庞大的旧代码库,需谨慎升级:先在某个分支上测试更严格的 hooks 校验规则,并修复它们标记出的问题。
  • 无论功能如何,如果您依赖 Server Components 且尚未应用安全补丁,应立即升级

总结

19.2 是一个低调但能显著提升日常工作效率的版本:Activity 改变了我们对保留状态的认知方式,useEffectEvent 消除了部分依赖处理技巧,而预渲染则缩小了静态页面与动态页面之间的差距。在全面推广之前,建议先在一个多标签页界面中进行测试。

相关阅读