距离 React 上次版本更新(v18.2)已经过去了600 多天。在这段时间里,React 社区的声音逐渐增多 ,其中不乏对 React 的期待、疑问和抱怨。那么,React 团队究竟在幕后忙些什么呢?本文将深入探讨 React 团队最近的研究进展,以期为大家揭示他们正在努力的方向。
React 编译器
React 编译器已经不再是单纯的研究项目,而是已经在 Instagram.com 的生产环境中得到了实际应用。React 团队正在努力将编译器推广至 Meta 的更多平台,并正在为首次开源发布做准备。
我们知道,React 在状态变化时有时会多次重新渲染。自 React 诞生之初,React 团队针对此类问题的解决方案一直是手动记忆化。在当前的 React API 中,这通常意味着使用 useMemo、useCallback 和 memo API 来手动控制 React 在状态变化时的重新渲染频率。然而,手动记忆化并非理想的解决方案。它会使代码变得复杂和混乱,容易出错,并且需要投入额外的工作来保持其最新状态。
尽管手动记忆化是一个实用的折衷方案,但 React 团队对此并不满足。他们的愿景是,当状态发生变化时,React 能够自动、精确地重新渲染 UI 的相关部分,而无需牺牲 React 的核心设计原则。React 团队认为,React 的核心思想:将 UI 视为状态的函数,并利用标准的 Java 值和习惯用法,这是 React 对如此多开发者具有吸引力的关键。为此, React 团队投入了大量精力来研发一个 React 的优化编译器。
考虑到 Java 语言的动态性和规则灵活性,对其进行优化往往极具挑战性。然而,React 编译器通过模拟 Java 的规则和“React 的规则”来安全地编译代码。例如,React 组件需遵循幂等性原则:在相同输入下应返回相同值,并且不得修改 props 或 state 值。这些规则不仅限制了开发者的操作范围,还为编译器优化提供了安全的空间。
当然,开发者有时会稍微违反一些规则,React 团队的目标是让 React 编译器能够尽可能多地在代码上直接运行。编译器会智能地检测代码是否严格遵循 React 的规则,如果确认安全,就会编译代码;若存在潜在风险,则会跳过编译。为了验证这一策略的有效性,目前正在使用 Meta 公司庞大且多样化的代码库进行测试。
对于希望确保代码遵循 React 规则的开发者,强烈推荐启用严格模式并配置 React 的 ESLint 插件。这些工具可以协助捕捉 React 代码中的潜在问题,提升应用质量,并为未来的功能(如 React 编译器)做好铺垫。React 团队正在完善 React 规则的官方文档,并更新 ESLint 插件,旨在帮助开发团队更好地理解和应用这些规则,从而构建更稳健的应用。
操作(Action)
React 团队正在探索通过“服务端操作”将客户端数据发送至服务端的解决方案,以便执行数据库变更和表单功能。在开发过程中,进一步扩展了这些 API,使其也支持仅在客户端应用中的数据处理。
为了简化这一综合功能集,将其统称为“操作”。通过“操作”,可以轻松地将函数传递给DOM元素,如
标签:<form action={search}>
<input name="query"/>
<button type="submit">Searchbutton>
form>
action 函数可以同步或异步运行。可以选择在客户端使用标准 Java 定义它们,或在服务端通过'use server'指令来实现。当使用操作时,React 将自动管理数据提交的生命周期,并提供如useFormStatus和useFormState等 Hook,使能够访问表单操作的当前状态和响应。
默认情况下,操作在转换过程中提交,确保在处理操作的同时,当前页面仍然保持交互性。由于操作支持异步函数,因此还增加了在转换过程中使用async/await的功能。这意味着,当发起异步请求(如fetch)时,可以通过转换的isPending状态来展示待处理的UI,并在应用更新期间持续显示该UI。
除了操作外,还推出了名为 useOptimistic 的新功能,用于管理乐观状态更新。此 Hook 允许应用临时更新,这些更新将在最终状态提交后自动回滚。useOptimistic 利用了常规的 async/await 机制,因此无论是在客户端使用 fetch,还是在服务端使用 Server Action,其工作方式都保持一致。
为了支持这一功能,库作者可以利用 useTransition 在自己的组件中实现自定义的 action={fn} 属性。鼓励库开发者在设计组件 API 时采纳操作模式,以确保为 React 开发者提供一致的使用体验。例如,如果库中包含一个
虽然 React 团队的初衷是专注于客户端与服务端之间的数据传输,通过服务端操作(Server Actions)来实现,但最终理念是为所有平台和环境提供统一的编程模型。因此,如果在客户端引入了新功能,会努力确保它也能在服务器端运行,反之亦然。这种统一的API设计使应用无论运行在何处都能保持一致性,从而简化了未来升级到不同环境的流程。
现在,操作(Actions)功能已在 Canary (预览版)中发布,并将随 React 的下一个版本正式推出。
React Canary (预览版)中的新功能
React Canary 的引入,提供了一种机制,允许在新功能的设计接近最终状态时,便能够采纳并使用这些稳定的特性,而无需等待它们被正式发布到稳定的版本中。
Canary 机制改变了开发 React 的方式。过去,新功能通常在 Meta 内部私下进行研究和构建,这意味着用户通常只能在功能完全成熟并被发布到稳定版本时才能体验到。然而,现在有了 Canary,React 团队选择在公开环境中与社区合作,共同完善在 React Labs 博客系列中分享的功能。这意味着,可以在功能仍在最终确定阶段时,就及时了解到这些新功能,而不是等到它们完全发布后。
目前,React Server Components、资源加载、文档元数据和操作等特性已经成功登陆 React Canary,并且已经在 react.dev 上为这些新特性提供了详细的文档支持: