React实验室:我们一直在做什么 – 2024年2月

2024年2月15日,由Joseph SavonaRicky HanlonAndrew ClarkMatt CarrollDan Abramov撰写。


在React实验室的文章中,我们写有关正在进行中的研究和开发的项目。自从我们的上次更新以来,我们取得了显著的进展,我们想要分享我们的进展。

注意

React Conf 2024定于5月15日至16日在内华达州亨德森举行!如果您有兴趣亲自参加React Conf,您可以在2月28日之前注册抽奖

有关门票、免费直播、赞助等更多信息,请参阅React Conf网站


React编译器

React编译器不再是一个研究项目:该编译器现在已经在生产中为instagram.com提供动力,我们正在努力将该编译器推广到Meta的其他平台,并准备发布第一个开源版本。

正如我们在之前的文章中讨论的,当状态发生变化时,React有时会过度重新渲染。自React早期以来,我们针对这种情况的解决方案一直是手动记忆化。在我们当前的API中,这意味着应用useMemouseCallbackmemo等API,手动调整React在状态更改时重新渲染的程度。但手动记忆化是一种妥协。它会使我们的代码变得混乱,容易出错,并且需要额外的工作来保持更新。

手动记忆化是一个合理的妥协,但我们并不满足。我们的愿景是,当状态更改时,React能够自动重新渲染UI的恰当部分,而不会妥协于React的核心思维模型。我们相信React的方法——将UI视为状态的简单函数,使用标准的JavaScript值和习惯用法——是React之所以对许多开发人员易于接近的关键部分。这就是为什么我们投资于构建React的优化编译器的原因。

JavaScript是一种因其松散规则和动态性而难以优化的语言。React编译器能够通过对JavaScript的规则和“React规则”建模来安全地编译代码。例如,React组件必须是幂等的——在给定相同输入的情况下返回相同的值——并且不能突变props或状态值。这些规则限制了开发人员可以做什么,并有助于为编译器提供优化的安全空间。

当然,我们明白开发人员有时会打破规则,我们的目标是使React编译器在尽可能多的代码上即插即用。编译器试图检测代码何时不严格遵循React的规则,并且将在安全的情况下编译代码,如果不安全则跳过编译。我们正在针对Meta庞大而多样的代码库进行测试,以帮助验证这种方法。

对于那些想确保其代码遵循React规则的开发人员,我们建议启用Strict Mode配置React的ESLint插件。这些工具可以帮助捕捉React代码中的微妙错误,提高应用程序的质量,并为即将推出的功能(如React编译器)未来提供支持。我们还正在制作关于React规则的综合文档,以及更新我们的ESLint插件,以帮助团队理解并应用这些规则,以创建更强大的应用程序。

要查看编译器的实际效果,您可以查看我们去年秋季的演讲。在演讲时,我们在instagram.com的一个页面上尝试了React编译器的早期实验数据。自那时以来,我们已经将编译器推广到了instagram.com的生产环境。我们还扩大了团队,以加速在Meta的其他平台上推出和开源编译器。我们对未来的道路感到兴奋,并将在未来几个月内分享更多信息。

Actions

我们之前分享过我们正在研究使用Server Actions从客户端发送数据到服务器的解决方案,以便执行数据库突变和实现表单。在Server Actions的开发过程中,我们扩展了这些API以支持在仅客户端应用程序中处理数据。

我们将这一更广泛的功能集合简称为“Actions”。Actions允许您将函数传递给DOM元素,例如<form/>

<form action={search}>
  <input name="query" />
  <button type="submit">Search</button>
</form>

action函数可以同步或异步操作。您可以在客户端使用标准JavaScript定义它们,或者在服务器上使用'use server'指令。在使用Action时,React将为您管理数据提交的生命周期,提供像useFormStatususeFormState这样的钩子,以访问表单操作的当前状态和响应。

默认情况下,Actions在过渡内提交,使当前页面在操作处理期间保持交互。由于Actions支持异步函数,我们还添加了在过渡中使用async/await的功能。这允许您在像fetch这样的异步请求开始时通过过渡的isPending状态显示待处理的UI,并在应用更新的整个过程中显示待处理的UI。

除了Actions,我们还引入了一个名为useOptimistic的功能,用于管理乐观状态更新。使用此钩子,您可以在客户端上乐观地设置数据的最终状态,假设提交成功,并恢复到从服务器接收的数据的值。它使用常规的async/await,因此无论您是在客户端上使用fetch还是在服务器上使用Server Action,它都可以正常工作。

库作者可以使用useTransition在自己的组件中实现自定义的action={fn}属性。我们的目标是当设计其组件API时,库采用Actions模式,为React开发人员提供一致的体验。例如,如果您的库提供了一个<Calendar onSelect={eventHandler}>组件,请考虑还提供一个<Calendar selectAction={action}>API。

虽然我们最初关注了用于客户端-服务器数据传输的Server Actions,但我们对React的理念是在所有平台和环境中提供相同的编程模型。如果可能的话,如果我们在客户端引入一个功能,我们也会让它在服务器上工作,反之亦然。这一理念使我们能够创建一套API,无论应用程序在何处运行,都能正常工作,从而更容易升级到不同的环境。

Actions现在在Canary频道中可用,并将在React的下一个版本中发布。

React Canary的新功能

我们引入了React Canaries作为在它们的设计接近最终之前采用单个新稳定功能的选项,而不是在稳定的semver版本中发布它们之前。

Canaries改变了我们开发React的方式。以前,功能会在Meta内部进行私下研究和构建,因此用户只会在发布到Stable时看到最终成品。有了Canaries,我们正在与社区的帮助下公开构建这些功能,以完成我们在React实验室博客系列中分享的功能。这意味着您可以更早地了解新功能,因为它们在最终完成之前就已经接近完成。

React Server Components、Asset Loading、Document Metadata和Actions都已经加入了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,如preloadpreinit,以在何时加载和初始化资源方面提供更大的控制。

  • 操作: 如上所述,我们添加了Actions来管理从客户端发送数据到服务器的操作。您可以将action添加到元素,如<form/>,使用useFormStatus访问状态,使用useFormState处理结果,并使用useOptimistic乐观地更新UI。

由于所有这些功能都共同工作,单独在Stable频道中发布它们是困难的。在没有配套的访问表单状态的情况下发布Actions将限制Actions的实际可用性。在没有集成Server Actions的情况下引入React Server Components将复杂化在服务器上修改数据的过程。

在我们可以将一组功能发布到Stable频道之前,我们需要确保它们可以协同工作,并且开发人员拥有在生产环境中使用它们所需的一切。React Canaries允许我们逐个开发这些功能,并逐步发布稳定的API,直到整个功能集完成。

React Canary中当前的功能集已经完成并准备好发布。

React的下一个主要版本

在经过几年的迭代后,react@canary现在已经准备好切换到react@latest。上述新功能与您的应用程序运行的任何环境兼容,为生产使用提供了一切所需。由于资产加载和文档元数据对一些应用程序可能是破坏性的更改,下一个React版本将是一个主要版本:React 19

为了准备发布,我们仍然有很多工作要做。在React 19中,我们还将添加一些长期要求的改进,这些改进需要破坏性变更,例如对Web组件的支持。我们现在的重点是完成这些变更,为发布做好准备,为新功能准备文档,并发布包含的公告。

在接下来的几个月里,我们将分享有关React 19包含的所有信息,如何采用新的客户端功能以及如何为React Server Components构建支持。

Offscreen(更名为Activity)

自上次更新以来,我们将正在研究的功能从“Offscreen”更名为“Activity”。名称“Offscreen”暗示它仅适用于应用程序中不可见的部分,但在研究该功能时,我们意识到应用程序的某些部分可能是可见但不活动的,例如模态框后面的内容。新名称更贴切地反映了标记应用程序的某些部分为“活动”或“非活动”的行为。

Activity仍在研究中,我们剩下的工作是最终确定向库开发人员公开的基本组件。在我们专注于发布更完整的功能之际,我们已将此区域放在了次要位置。


除了此更新外,我们的团队还在会议上发表演讲,并出现在播客中,以更详细地介绍我们的工作并回答问题。

感谢Lauren TanSophie AlpertJason BontaEli WhiteSathya Gunasekaran对本文的审阅。

感谢阅读,并期待在React Conf见

2024-02-28

访问量 89

扫码关注公众号“前端微志”

第一时间获取新周刊

预览图片