React 19.3 带来了一组面向现代浏览器和复杂 UI 的新能力,包括 View Transitions、Fragment Refs、browser() 和 Trusted Types。它们覆盖了页面切换动画、Fragment 级 DOM 操作、浏览器环境处理以及客户端安全策略。升级的重点不只是改版本号,而是确认应用的构建链、浏览器兼容策略和安全配置能否承接这些能力。
这次更新解决了哪些问题
过去,React 应用实现页面切换动画,通常要依赖第三方动画库、手动维护 CSS class,或者把旧内容和新内容同时保留在 DOM 中。View Transitions 为浏览器提供了一套原生过渡机制,React 可以围绕它组织 UI 更新,让“从当前界面切换到下一个界面”的过程更自然。
Fragment Refs 则面向另一类问题:一个组件可能返回多个兄弟节点,但调用方仍然希望以一个整体管理这些节点,例如设置焦点、观察可见性、处理事件或执行 DOM 操作。Fragment 级引用可以减少为了获得一个父容器而额外增加包装元素的需求。
browser() 和 Trusted Types 分别指向运行环境与安全边界。前者适合需要明确区分浏览器环境的代码路径;后者可以帮助应用配合浏览器的 Trusted Types 策略,降低不安全 HTML 注入进入 DOM 的风险。具体 API 形态和可用范围应以项目所使用的 React 19.3 发布说明及构建环境为准。
View Transitions 的落地方式
可以先把 View Transition 当作一个渐进增强能力:支持该浏览器 API 时使用过渡,不支持时仍然正常更新 React 状态。下面的示例展示了一个可以改造到 React 项目中的标签切换组件。示例假设应用运行在支持 document.startViewTransition 的浏览器中,并为不支持的环境保留了普通更新路径。
运行前,将代码放入一个已有 React 19.3 工程的组件文件中,例如 ViewTabDemo.jsx。
import { useState } from "react";
const tabs = [
{ id: "overview", label: "概览", content: "这是概览内容。" },
{ id: "activity", label: "活动", content: "这是活动内容。" },
{ id: "settings", label: "设置", content: "这是设置内容。" },
];
export default function ViewTabDemo() {
const [activeId, setActiveId] = useState("overview");
const activeTab = tabs.find((tab) => tab.id === activeId);
function changeTab(nextId) {
if (nextId === activeId) return;
const update = () => setActiveId(nextId);
if (typeof document.startViewTransition === "function") {
document.startViewTransition(update);
} else {
update();
}
}
return (
<section>
<nav aria-label="内容标签">
{tabs.map((tab) => (
<button
key={tab.id}
type="button"
aria-selected={tab.id === activeId}
onClick={() => changeTab(tab.id)}
>
{tab.label}
</button>
))}
</nav>
<article className="tab-panel" aria-live="polite">
<h2>{activeTab.label}</h2>
<p>{activeTab.content}</p>
</article>
</section>
);
}
再加入最小的 CSS 过渡规则:
.tab-panel {
view-transition-name: tab-panel;
}
::view-transition-old(tab-panel),
::view-transition-new(tab-panel) {
animation-duration: 180ms;
animation-timing-function: ease-out;
}
这个示例的关键点有三个:状态更新仍由 React 管理;View Transition 只包住一次状态更新;不支持原生 API 时不会阻断功能。实际项目中还需要检查用户的 prefers-reduced-motion 设置,并避免给高频更新,例如输入框每次按键,都启动过渡动画。
Fragment Refs 与 DOM 边界
Fragment Refs 适合组件返回多个节点但不希望引入额外包装元素的场景。可以这样评估是否值得使用:
- 组件确实需要返回多个并列节点。
- 调用方需要把这些节点视为一个可管理的集合。
- 增加 wrapper 会影响布局、语义或 CSS 选择器。
- 团队已经确认当前 React 19.3 版本、类型定义和构建工具支持目标 API。
不要为了“使用新 API”而把所有 ref 都改成 Fragment Ref。一个明确的容器元素往往更容易调试,也更容易被测试工具定位。对于焦点管理、Intersection Observer、事件绑定等功能,应优先验证 Fragment Ref 提供的实际方法和生命周期行为,再封装到业务组件中。
Trusted Types 不只是 React 配置
Trusted Types 需要浏览器 CSP、应用代码和第三方库一起配合。仅仅升级 React 并不会自动修复所有 HTML 注入风险。应用仍然应该避免把未经校验的字符串传入 dangerouslySetInnerHTML,并审查富文本渲染、Markdown 转 HTML、第三方编辑器以及脚本加载逻辑。
可以在部署配置中先以报告模式观察违规来源。下面是一个示意性的 HTTP 响应头配置,具体报告地址需要替换成项目自己的收集端点:
Content-Security-Policy-Report-Only: trusted-types default; require-trusted-types-for 'script'; report-uri /security/csp-report
建议先在测试环境和一小部分生产流量中启用报告,再逐步切换到强制策略。若应用依赖的库仍会直接写入 HTML,强制启用可能造成运行时错误,因此需要先定位并升级、替换或封装这些依赖。
升级检查清单
升级 React 19.3 时,可以按以下顺序推进:
- 固定 React、React DOM、类型包和构建工具的版本,避免只升级单个依赖。
- 在目标浏览器中验证 View Transitions 的降级路径和减少动画设置。
- 对 Fragment Refs 编写焦点、可见性和卸载行为测试,不要只测试初次渲染。
- 搜索
dangerouslySetInnerHTML、HTML 字符串拼接和第三方 DOM 操作点。 - 先使用 CSP 报告模式收集 Trusted Types 违规,再决定强制策略范围。
- 检查服务端渲染、客户端 hydration、测试环境和旧浏览器构建是否仍然通过。
React 19.3 的价值在于把 UI 过渡、Fragment 级管理、浏览器环境和安全策略放到同一个升级窗口中考虑。实际采用时应按功能拆分:先升级并验证基础渲染,再逐个启用 View Transitions、Fragment Refs 和 Trusted Types,而不是一次性改变全部组件。这样遇到兼容性或第三方依赖问题时,回滚和定位都会更简单。