2024-02-21
React
0
请注意,本文编写于 88 天前,最后修改于 88 天前,其中某些信息可能已经过时。

目录

React 编译器
Actions
React Canary 新功能
React 下一个主版本:React 19
Offscreen(重命名为 Activity)

React 编译器

React 编译器已经不再是一个研究项目:编译器现已为 instagram.com 的生产环境提供支持,而且我们正努力将其推广到 Meta(前 FaceBook) 的更多平台,并准备首次开源发布。

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

手动记忆化是一种合理的妥协,但我们并不满意。我们的愿景是让 React 在状态更改时 自动 重新渲染 UI 的正确部分,而不会影响 React 的核心心智模型。我们相信 React 的方法 —— UI 作为状态的简单函数,具有标准的 JavaScript 值和习语 —— 是 React 对于众多开发人员来说平易近人的关键。这就是我们投入构建 React 优化编译器的原因。

规则松散且具有动态性使得 JavaScript 成为一种臭名昭著的难以优化的语言。React 编译器能够通过对 JavaScript 的规则和“React 的规则”进行建模来安全地编译代码。例如,React 组件必须是幂等的 —— 给定相同的输入必须返回相同的值 —— 不能改变 props 或 state 值。这些规则限制了开发者可以做的事情,并有助于为编译器优化开辟一个安全的空间。

当然,我们理解开发者有时会稍微改变规则,我们的目标是让 React 编译器尽可能开箱即用地处理更多代码。编译器会尝试检测代码是否严格遵循 React 的规则,并且会在安全的情况下编译代码,或者在不安全的情况下跳过编译。我们正针对 Meta 庞大且多样的代码库进行测试以帮助验证这一方法。

对于希望代码严格遵循 React 规则的开发人员,我们建议启用严格模式配置 React 的 ESLint 插件。这些工具可以帮助捕获 React 代码中的细微错误,从而提高应用程序的质量,并为 React 编译器等即将推出的功能做好准备。我们还在整理 React 规则的文档,并更新我们的 ESLint 插件,以帮助团队理解和应用这些规则,从而创建更强大的应用程序。

要了解编译器的实际应用,您可以查看我们去年秋天的演讲。在演讲时,我们尝试在 instagram.com 的一页上使用 React 编译器获得了早期实验数据。从那时起,我们已将编译器运用于 instagram.com 的实际生产环境中。我们也扩大了团队来加速在 Meta 和开源领域的其他应用的推出。我们对未来的道路感到兴奋,并且将在未来几个月内分享更多信息。

Actions

我们之前分享过,我们正探索使用 Server Actions(服务器操作)从客户端向服务器发送数据的解决方案,这样我们可以执行数据库变更并实现表单。在 Server Actions 开发过程中,我们扩展了这些 API 来支持纯客户端 App 中数据的处理。

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

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

action 函数可以同步或异步操作。你可以使用标准 JavaScript 在客户端定义它们,也可以使用 'use server' 指令在服务器上定义。使用 action 时,React 会管理数据提交的生命周期,提供例如 useFormStatususeFormState 等 hooks,访问表单操作的当前状态和响应。

默认情况下,Actions 在 transition 里提交,这样在处理 Actions 时,可以保证当前页面的交互性。由于 Actions 支持异步函数,我们还添加了在 transitions 中使用 async/await 的功能。这允许你在类似 fetch 等异步请求启动时,显示 transition 的 isPending 状态的待定 UI,并在应用更新的整个过程中显示待定 UI。

除了 Actions 外,我们还引入了一项名为 useOptimistic 的功能用于管理积极状态更新。通过这个钩子,你可以应用临时更新,一旦最终状态提交,更新会自动恢复。对于 Actions 来说,这允许你在客户端乐观地设置数据的最终状态,假设提交是成功的,并在从服务器收到数据后还原到该值。它使用常规的 async/await 工作,所以无论你是在客户端使用 fetch ,还是在服务器使用 Server Action,它的工作方式都是相同的。

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

虽然我们最初聚焦于于客户端-服务器数据传输的 Server Actions,但我们的 React 理念是在所有平台和环境中提供相同的编程模型。如果可以的话,如果我们在客户端引入一项功能,我们的目标是使其也可以在服务器上运行,反之亦然。这一理念使我们能够创建一组 API,无论您的 App 在哪运行,它们都可以奏效,从而使以后能够更轻松地升级到不同的环境。

Actions 现已在 Canary 通道中提供,并将在 React 的下个版本中发布。

React Canary 新功能

我们引入了 React Canaries 作为一种可以在设计接近最终版本后立即采用各个新型稳定功能,然后再以稳定的语义版本发布的选择。

Canary 改变了我们开发 React 的方式。此前,功能会在 Meta 内部私下研发和构建,因此用户仅能在稳定版发布时才看到最终的打磨产品。有了 Canaries,我们正在社区的辅助下公开构建,以完成我们在 React Labs 博客系列中分享的功能。这意味着您会更快了解到新功能,因为此时它们正在锅里,而不是已经出锅。

React Server Components(React 服务器组件)、Asset Loading(资源加载)、Document Metadata(文档元数据)和 Actions 都已经在 React Canary 中发布,我们已经在 react.dev 上为这些功能添加了文档:

  • 指令:"use client""use server" 是专为全栈 React 框架设计的打包器功能。它们标记两个环境之间的“分割点”:"use client" 表明打包器生成 <script> 标签(比如 Astro Island),而 "use server" 告诉打包器生成 POST 端点(比如 tRPC Mutations)。它们一起让我们可以编写可复用组件,这些组件将客户端交互与相关的服务器端逻辑组合在一起。
  • 文档元数据:我们添加了对在组件树中任意位置渲染 <title><meta><link> 标签的内置支持。它们在所有环境中都殊途同归,包括完全客户端代码、SSR 和 RSC。这为 React Helmet 等库开创的功能提供了内置支持。
  • 资源加载:我们将 Suspense 于样式表、字体和脚本等资源的加载生命周期集成在一起,这样 React 会通过考虑它们来确定 <style><link><script> 是否已经准备好加载并展示。我们还添加了新的资源加载 API,比如 proloadpreinit,从而更好地控制资源何时加载和初始化。
  • Actions:我们添加了 Actions 来管理从客户端向服务器发送数据。我们可以将 action 添加到 <form/> 等元素,使用 useFormStatus 访问状态,使用 useFormState 处理结果,并使用 useOptimistic 积极更新 UI。

由于这些功能“梦幻联动”,因此很难在稳定频道中单独发布它们。在没有访问表单状态的补充钩子的情况下,发布 Actions 会限制其实际可用性。在不集成 Server Actions 的情况下引入 React Server Components 会使服务器上的数据修改变得复杂。

在我们向稳定通道发布一组功能之前,我们需要确保它们能够协同工作,并且开发者拥有在生产中使用它们所需的一切。 React Canaries 允许我们单独开发这些功能,并逐步发布稳定的 API,直到整个功能集完成。

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

React 下一个主版本:React 19

经过数年迭代,react@canary 现已准备好交付给 react@latest。上述新功能与您的 App 运行的任何环境兼容,提供生产使用所需的一切。由于资源加载和文档元数据对于某些 App 而言可能是一个重大变化,因此 React 的下个版本会是一个主要版本:React 19

为发布做准备还有更多工作要做。在 React 19 中,我们还添加了长期要求的改进,这些改进需要重大更改,比如对 Web Components 的支持。我们现在的重点是落实这些更改,准备发布,最终确定新功能的文档,并发布所包含内容的公告。

在接下来的几个月中,我们会共享有关 React 19 包含的所有内容、如何采用新客户端功能,以及如何构建对 React Server Components 的支持的更多信息。

Offscreen(重命名为 Activity)

自上次更新以来,我们正在研究的一项功能从“Offscreen”重命名为“Activity”。“Offscreen”这个名称意味着,它仅适用于 App 中不可见的部分,但在研究该功能时,我们意识到 App 的某些部分可能是可见但未激活的,比如模态框后面的内容。新名称更准确地反映了将 App 的某些部分标记为“激活”或“失活”的行为。

Activity 仍在研发中,我们剩下的工作是最终确定向库开发者暴露的原语。我们已经取消了该领域的优先级,同时聚焦于更完整的交付功能。

本文作者:Morales

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!