React Labs: 我们一直在努力的方向 – 2024 年 2 月
2024 年 2 月 15 日由 Joseph Savona,Ricky Hanlon,Andrew Clark,Matt Carroll 和 Dan Abramov 撰写。
在 React Labs 文章中,我们讨论了正在积极研究和开发的项目。自上次更新以来,我们取得了重大进展,我们很乐意与大家分享我们的进展。
React 编译器
React 编译器不再是一个研究项目:该编译器现在为 instagram.com 提供生产环境支持,我们正在努力将编译器部署到 Meta 的更多平台,并准备第一个开源版本。
如我们之前文章中所述,当状态发生变化时,React
手动记忆是一种合理的折衷方案,但我们并不满意。我们的愿景是让 React
JavaScript 由于其松散的规则和动态特性,一直是难以优化的语言。React 编译器能够通过对 JavaScript
当然,我们理解开发人员有时会稍微弯曲规则,我们的目标是让 React 编译器尽可能地开箱即用。编译器会尝试检测代码是否严格遵循 React
对于那些想要确保他们的代码遵循 React 规则的开发人员,我们建议
要查看编译器的实际运行情况,您可以查看我们
操作
我们之前分享了我们正在探索使用服务器操作将数据从客户端发送到服务器的解决方案,以便您可以执行数据库变更和实现表单。在开发服务器操作期间,我们将这些 API 扩展到也支持客户端应用程序中的数据处理。
我们将这组更广泛的功能简称为“操作”。操作允许您将函数传递给 DOM 元素,例如
<form action={search}>
<input name="query" />
<button type="submit">Search</button>
</form>
该 action
函数可以同步或异步执行。您可以在客户端使用标准 JavaScript 定义它们,也可以在服务器上使用
默认情况下,操作会在 过渡 中提交,在操作处理期间保持当前页面可交互。由于操作支持异步函数,我们还添加了在过渡中使用 async/await
的功能。这允许你在异步请求(如 fetch
)开始时,使用过渡的 isPending
状态显示待处理的 UI,并在更新应用过程中一直显示待处理的 UI。
除了操作之外,我们还引入了一个名为 useOptimistic
的功能,用于管理乐观状态更新。使用此钩子,你可以应用临时更新,这些更新会在最终状态提交后自动恢复。对于操作,这允许你乐观地设置客户端上数据的最终状态,假设提交成功,然后恢复到从服务器接收到的数据的该值。它使用常规的 async
/await
,因此无论你是在客户端使用 fetch
,还是从服务器使用服务器操作,它的工作原理都是一样的。
库作者可以使用 useTransition
在他们自己的组件中实现自定义 action={fn}
属性。我们的目的是让库在设计组件 API 时采用操作模式,为 React 开发人员提供一致的体验。例如,如果你的库提供了一个 <Calendar onSelect={eventHandler}>
组件,也考虑公开一个 <Calendar selectAction={action}>
API。
虽然我们最初将重点放在服务器操作用于客户端-服务器数据传输,但我们对 React 的理念是在所有平台和环境中提供相同的编程模型。在可能的情况下,如果我们在客户端引入一个功能,我们希望让它也能在服务器上工作,反之亦然。这种理念使我们能够创建一组可以在应用程序运行的任何地方工作的 API,从而更容易地升级到不同的环境。
操作现在可以在 Canary 渠道中使用,并将包含在下一个版本的 React 中。
React Canary 中的新功能
我们引入了 React Canary 作为一种选择,以便在稳定语义版本中发布之前,尽早采用单个新的稳定功能,只要其设计接近最终状态。
Canary 是我们开发 React 的方式的改变。以前,功能会在 Meta 内部私下进行研究和构建,因此用户只会在发布到稳定版时才会看到最终的完善产品。使用 Canary,我们将在社区的帮助下公开构建,以最终确定我们在 React Labs 博客系列中分享的功能。这意味着你可以更早地了解新功能,因为它们正在最终确定,而不是在完成之后。
React 服务器组件、资产加载、文档元数据和操作已全部在 React Canary 中上线,我们还在 react.dev 上添加了这些功能的文档。
-
指令:
"use client"
和"use server"
是为全栈 React 框架设计的捆绑程序功能。它们标记了两种环境之间的“分割点”:"use client"
指示捆绑程序生成一个<script>
标签(如 Astro Islands),而"use server"
告诉捆绑程序生成一个 POST 端点(如 tRPC Mutations)。它们共同让你编写可重用的组件,这些组件将客户端交互与相关的服务器端逻辑组合在一起。 -
文档元数据: 我们添加了对渲染
<title>
、<meta>
和元数据<link>
标签的内置支持,这些标签可以位于你的组件树中的任何位置。它们在所有环境中都以相同的方式工作,包括完全客户端代码、SSR 和 RSC。这为像 React Helmet 这样的库开创的功能提供了内置支持。 -
资产加载: 我们将 Suspense 与资源(如样式表、字体和脚本)的加载生命周期集成在一起,以便 React 能够将它们考虑在内,以确定像
<style>
、<link>
和<script>
这样的元素中的内容是否已准备好显示。我们还添加了新的 资源加载 API,如preload
和preinit
,以提供对何时应该加载和初始化资源的更大控制权。 -
操作: 如上所述,我们添加了操作来管理从客户端发送数据到服务器。你可以将
action
添加到像<form/>
这样的元素,使用useFormStatus
访问状态,使用useActionState
处理结果,并使用useOptimistic
乐观地更新 UI。
由于所有这些功能都协同工作,因此很难在稳定渠道中单独发布它们。在没有访问表单状态的互补钩子情况下发布操作将限制操作的实用性。在没有集成服务器操作的情况下引入 React 服务器组件将使修改服务器上的数据变得复杂。
在我们能够将一组功能发布到稳定渠道之前,我们需要确保它们能够协同工作,并且开发人员拥有在生产中使用它们所需的一切。React Canary 使我们能够单独开发这些功能,并以增量方式发布稳定 API,直到整个功能集完成。
React Canary 中的当前功能集已完成并准备发布。
React 的下一个主要版本
经过几年的迭代,react@canary
现在已准备好发布到 react@latest
。上面提到的新功能与您的应用程序运行的任何环境兼容,提供生产使用所需的一切。由于资产加载和文档元数据可能会对某些应用程序产生重大更改,因此 React 的下一个版本将是一个主要版本:React 19。
为了准备发布,我们还有更多工作要做。在 React 19 中,我们还添加了长期要求的改进,这些改进需要重大更改,例如对 Web 组件的支持。我们现在关注的是实现这些更改,准备发布,完善新功能的文档,并发布包含内容的公告。
我们将在未来几个月分享有关 React 19 包含的所有内容、如何采用新客户端功能以及如何构建对 React 服务器组件的支持的更多信息。
Offscreen(更名为 Activity)。
自上次更新以来,我们已将正在研究的功能从“Offscreen”更名为“Activity”。名称“Offscreen”暗示它仅适用于应用程序中不可见的部件,但在研究此功能时,我们意识到应用程序的某些部分可以是可见的但处于非活动状态,例如模态后面的内容。新名称更准确地反映了将应用程序的某些部分标记为“活动”或“非活动”的行为。
Activity 仍在研究中,我们剩余的工作是最终确定公开给库开发人员的原语。在我们将重点放在发布更完整的功能时,我们已降低了此领域的优先级。
除了本次更新之外,我们的团队还在会议上发表了演讲,并在播客中露面,以便更多地介绍我们的工作并回答问题。
-
Sathya Gunasekaran 在React India 大会上介绍了 React 编译器。
-
Dan Abramov 在RemixConf 大会上发表了题为“React from Another Dimension”的演讲,探讨了 React 服务器组件和操作的另一种创建历史。
-
Dan Abramov 在Changelog 的 JS Party 播客 上接受了关于 React 服务器组件的采访。
-
Matt Carroll 在Front-End Fire 播客 上接受了采访,他在采访中讨论了The Two Reacts。
感谢Lauren Tan、Sophie Alpert、Jason Bonta、Eli White 和Sathya Gunasekaran 对本文的审阅。
感谢您的阅读,并在 React Conf 上见!