React v19 正式发布!(react15)

boyanx1天前技术教程2

React 于 2024 年 12 月 06 日正式发布,为开发者带来了诸多令人兴奋的新特性和改进。下面对 React 19 版本中的核心更新和主要改进做一个快速介绍。

React 19 核心更新

Actions

React 19 引入了 Actions 概念,通过支持异步函数,简化了处理待定状态、错误、乐观更新以及表单的逻辑。

  • Pending 状态管理:使用useActionStateuseFormStatus 等新hook轻松处理表单的加载状态。
  • React DOM:<form> Actions<form action={actionFunction}>
  • 错误处理(errors):集成错误边界,简化错误回退逻辑。
  • 乐观更新(optimistic updates):通过useOptimistic 实现实时数据更新。
function ChangeName({currentName, onUpdateName}) {
  const [optimisticName, setOptimisticName] = useOptimistic(currentName);

  const submitAction = async formData => {
    const newName = formData.get("name");
    setOptimisticName(newName);
    const updatedName = await updateName(newName);
    onUpdateName(updatedName);
  };

  return (
    <form action={submitAction}>
      <p>Your name is: {optimisticName}</p>
      <p>
        <label>Change Name:</label>
        <input
          type="text"
          name="name"
          disabled={currentName !== optimisticName}
        />
      </p>
    </form>
  );
}

新的 React DOM 静态 API

在 React 19 中,为react-dom/static 新增了prerenderprerenderToNodeStream两个 API,用于改进静态 HTML 生成。它们专为支持流式环境(如 Node.js Streams 和 Web Streams)而设计。

import { prerender } from 'react-dom/static';

async function handler(request) {
  const {prelude} = await prerender(<App />, {
    bootstrapScripts: ['/main.js']
  });
  return new Response(prelude, {
    headers: { 'content-type': 'text/html' },
  });
}

在返回静态 HTML 流之前,预渲染 API 会等待所有数据加载完毕。 流可以转换为字符串,也可以与流响应一起发送。 它们不支持加载时的流式内容,而现有的 React DOM 服务器呈现 API 支持流式内容。

React 服务端组件

React 19 将 Server Components 功能推向稳定,并引入了相关的 API 和最佳实践。

Server Components:

Server Components 是一种新选项,允许在客户端应用或 SSR 服务端之外的环境中预先渲染组件。这一独立环境即为 React 服务端组件中的“服务端”。Server Components可以在 CI 服务器上构建时运行一次,也可以在每个请求时通过 Web 服务器运行。

React 19 包括来自 Canary 版本的所有服务端组件功能。这意味着支持服务端组件的库现在可以将 React 19 作为对等依赖项(peer dependency),并通过 react-server 导出条件在支持全栈 React 架构的框架中使用。

Server Actions:

Server Actions 允许客户端组件调用在服务器上执行的异步函数。 当使用use server 指令定义服务器动作时,框架会自动创建服务器函数的引用,并将该引用传递给客户端组件。 当客户端调用该函数时,React 将向服务器发送请求以执行该函数,并返回结果。

React 19 主要改进

ref 作为属性

从 React 19 开始,函数组件可以通过属性访问ref,不再需要forwardRef,未来将弃用并移除forwardRef

function MyInput({placeholder, ref}) {
  return <input placeholder={placeholder} ref={ref} />
}

//...
<MyInput ref={ref} />

Hydration 错误的差异报告

在 React 19 中,我们改进了 react-dom 对 hydration 错误的差异报告。例如,之前在开发环境中,React 可能会记录多个没有详细信息的错误:

现在,我们会记录一条包含错误差异的消息:

<Context>as a provider

在 React 19 中,您可以将<Context> 作为 provider,无需再使用<Context.Provider>

const ThemeContext = createContext('');

function App({children}) {
  return (
    <ThemeContext value="dark">
      {children}
    </ThemeContext>
  );  
}

Ref 清理函数

从 React 19 开始,支持从 ref 回调中返回一个 Ref 清理函数(当元素从 DOM 中被移除):

<input
  ref={(ref) => {
    // ref created

    // NEW: return a cleanup function to reset
    // the ref when element is removed from DOM.
    return () => {
      // ref cleanup
    };
  }}
/>

原生支持 Document Metadata

React 19 现在原生支持<title><meta><link>等文档元数据标签,简化了 SEO 和元数据管理逻辑。过去,这些元素需要通过 effect 手动插入,或者通过类似react-helmet 的库来实现,同时在服务器端渲染(SSR)时需要特别小心处理。

function BlogPost({post}) {
  return (
    <article>
      <h1>{post.title}</h1>
      <title>{post.title}</title>
      <meta name="author" content="Josh" />
      <link rel="author" href="https://twitter.com/joshcstory/" />
      <meta name="keywords" content={post.keywords} />
      <p>
        Eee equals em-see-squared...
      </p>
    </article>
  );
}

支持样式表

样式表(包括外部链接的<link rel="stylesheet" href="..."> 和内联的<style>...</style>)在 DOM 中需要仔细定位以遵循样式优先级规则。构建一种可以在组件中组合使用的样式表功能非常困难,因此用户往往会选择将所有样式集中加载,远离依赖它们的组件,或者使用封装了这些复杂性的样式库。

在 React 19 中,我们解决了这些复杂性,并通过内置样式表支持,实现了与客户端的并发渲染和服务器端的流式渲染的更深集成。如果您告诉 React 样式表的优先级,它将管理样式表在 DOM 中的插入顺序,并确保外部样式表在显示依赖于这些样式规则的内容之前加载完成。

function ComponentOne() {
  return (
    <Suspense fallback="loading...">
      <link rel="stylesheet" href="foo" precedence="default" />
      <link rel="stylesheet" href="bar" precedence="high" />
      <article class="foo-class bar-class">
        {...}
      </article>
    </Suspense>
  )
}

function ComponentTwo() {
  return (
    <div>
      <p>{...}</p>
      <link rel="stylesheet" href="baz" precedence="default" />  <-- will be inserted between foo & bar
    </div>
  )
}

支持异步脚本

在 HTML 中,普通脚本(<script src="...">)和延迟脚本(<script defer="" src="...">)会按照文档顺序加载,这使得在组件树深处渲染这些脚本变得具有挑战性。而异步脚本(<script async="" src="...">)则会以任意顺序加载。

在 React 19 中,我们改进了对异步脚本的支持,允许您在组件树的任何位置渲染它们,直接放置在真正依赖该脚本的组件内部,而无需手动管理脚本实例的重定位和去重。

function MyComponent() {
  return (
    <div>
      <script async={true} src="..." />
      Hello World
    </div>
  )
}

function App() {
  <html>
    <body>
      <MyComponent>
      ...
      <MyComponent> // won't lead to duplicate script in the DOM
    </body>
  </html>
}

资源预加载

在初始文档加载和客户端更新过程中,尽早告知浏览器可能需要加载的资源会对页面性能产生巨大影响。

React 19 包含大量用于加载和预加载浏览器资源的全新 API,可让您尽可能轻松地构建出色的体验,而不会因为资源加载效率低下而停滞不前。

import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'
function MyComponent() {
  preinit('https://.../path/to/some/script.js', {as: 'script' }) // loads and executes this script eagerly
  preload('https://.../path/to/font.woff', { as: 'font' }) // preloads this font
  preload('https://.../path/to/stylesheet.css', { as: 'style' }) // preloads this stylesheet
  prefetchDNS('https://...') // when you may not actually request anything from this host
  preconnect('https://...') // when you will request something but aren't sure what
}
<!-- the above would result in the following DOM/HTML -->
<html>
  <head>
    <!-- links/scripts are prioritized by their utility to early loading, not call order -->
    <link rel="prefetch-dns" href="https://...">
    <link rel="preconnect" href="https://...">
    <link rel="preload" as="font" href="https://.../path/to/font.woff">
    <link rel="preload" as="style" href="https://.../path/to/stylesheet.css">
    <script async="" src="https://.../path/to/some/script.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

更多参考官方文章:https://react.dev/blog/2024/12/05/react-19

相关文章

在 .NET Core 中使用 SignalR 实现实时通信应用程序

概述:在现代 Web 开发环境中,对实时功能的需求越来越大。无论是实时聊天、实时通知还是动态仪表板,用户都希望获得即时更新。SignalR 是一个用于 ASP.NET 的库,可简化向应用程序添加实时...

PuePy:将Python带入浏览器的革命性框架

在现代网络开发中,JavaScript无疑是主导地位的编程语言。但最近,随着WebAssembly和PyScript的崛起,Python的使用场景逐渐扩展到了前端开发领域。PuePy应运而生,作为一...

input输入框最常用样式修改(input框不能修改)

input框有默认的样式,但在实际项目开发中,经常要根据美工的设计图对输入框的样式进行修改,这里把我在项目中最常用到的关于input样式修改的代码进行了整理,可以用于学习,也可直接运用。修改input...

用deepseek开发一款记事日历(留白记事deepseek软件做什么用)

打开 chat.deepseek.com输入提示词: 制作一个记事日历工具,每个月自动更新当前的月份,每天可以添加当天的备注,点击后即标记为完成结果:<!DOCTYPE html> <...

前端面试模拟:常见的3个JavaScript经典考题

在一次备受期待的前端开发高级岗位面试中,你紧张地走进了会议室,对面坐着的是一位经验丰富的技术面试官。窗外阳光明媚,屋内却有一丝令人紧张的静谧。第一问:如何使用JavaScript实现事件委托?面试官微...

OneCode设计器协议栈名词解析及标准概念适配

前言以下是基于 OneCode 技术体系,对标准协议内容进行适配性转换与解读(因 OneCode 有其自身生态规范,会结合其常见概念和流程调整表述,部分需结合 OneCode 实际框架灵活落地 ):一...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。