第 84 期 - React19 新特性全解析
摘要
文章主要介绍了 React19 在 2024 年 12 月 5 日发布后的新特性,包括概念方面的 transition、Optimistic,新的 hook 如 useActionState、useOptimistic、useFormStatus 等,还阐述了服务端组件的相关特性、改进之处以及一些特性在用户体验和开发体验上的提升等内容。
一、基础概念
文章先补充了一些基本概念。
- transition 与 state:React18 加入了 transition 概念,类似 state,但有所区分,React18 将 transition 定义为非紧急更新(过渡更新),state 为紧急更新。例如输入框与用户交互直接相关,属于紧急更新;下拉框非直接交互,为非紧急更新。
- Optimistic 乐观:React19 新加入此概念,其实 React18 中已有所应用,如过渡更新涉及乐观更新。所谓乐观,是指认为页面 99%几率会成功更新,API 和交互写法优先考虑此场景。
二、React19 新特性
(一)Actions 相关
- 异步函数支持:React19 在 transition 中添加了对异步函数的支持,状态变更时 React 会处理 pending、error、result。通过前后代码示例对比,以前处理异步请求时需要额外设置 pending 状态,现在使用 useTransition 或 startTransition 更简洁地实现了相同功能,保证了状态变更时 UI 的响应和连续性。
- 新 hook:useActionState:在此基础上,React19 添加了两个 hook API,useActionState 针对一般情况。通过示例展示了在 form 中的简化写法。
- useFormStatus:这是 React DOM 的新 hook。示例代码展示了其具体用法,它提供上一个 form 提交的状态信息,包括 pending(布尔值,表示父<form>是否在提交中)、data(基于 FormData interface 的对象,包含父 form 提交的数据,无提交或无父 form 则为 null)、method('get'或'post',表示父 form 提交的方法,默认 GET)、action(用户在父 form 定义的 action 函数引用,否则为 null)。并且要注意 useFormStatus 必须用在渲染 form 的组件内部。
(二)乐观 hook:useOptimistic
- 乐观渲染原理:从 A 页面切换到 B 页面的示例解释了乐观的概念,正常需要先完成异步函数再渲染 B 页面,但乐观的做法是在异步完成之前先切换页面。useOptimistic 就是实现乐观渲染的 Hook,通过代码示例展示了 optimisticState.count 的更新与 Button 的 pending 和 console.log 的变更。
- 乐观的错误处理:如果错误发生,乐观值会自动回滚到上一次。
(三)use 的特性
- 读取 promise 和 context:use 不同于传统 hook 规则,可用在条件或者循环语句读取 context。示例展示了 use 读取 promise 的用法,包括返回 promise 的函数以及在不同组件中的使用。
- 支持异步:use 可读取 promise,还展示了读取 context 的示例代码,解释了其在不同场景下(如条件式调用)可行的原因是 context 的存储不同于普通 hooks,普通 hooks 的值存储在 hooks 单链表中,而 context 存储在单独的 stack 中。最后给出了 use 的源码分析。
三、服务端组件相关
(一)New React DOM Static APIs
- 现在的服务端组件可以使用 async/await 函数。以前需要使用 useEffect 或者 next 提供的 API(如 getServerSideProps 或者 getStaticProps 函数),React19 新增了用于 static site generation(SSG)的 API,用于代替 renderToString(因为 renderToString 不支持流式布局)。
(二)服务端组件特性
- 没有 Server 的 Server 组件:通过前后代码示例对比,以前组件在 bundle.js 中,加载内容在首次页面渲染之后,现在组件在渲染期间(app 构建时)加载内容,渲染出的内容可在 SSR 中转成 HTML 并上传到 CDN,客户端无需加载原组件和执行异步操作。给出了使用 fake api 和本机服务(如 koa - lemon 中的 server.js)的示例。
- Server 里的 Server Components:同样通过前后代码对比,以前组件在首次渲染后加载数据,会导致客户端 - 服务端的瀑布流现象,现在在渲染期间加载数据,提高了效率。还给出了 yu - next 中可运行的多个示例,包括静态页面和动态页面的示例,并且阐述了服务端组件在服务端完成渲染不能使用客户端交互 API(如 useState),如果涉及交互可抽离组件并标记为客户端组件的方法。
四、React19 的改进之处
- ref 作为 prop:从 19 开始,ref 可以作为 prop 在函数组件中使用,以前函数组件转发 ref 必须使用 forwardRef,这意味着 forwardRef 以后可能被弃用,这对组件库有较大影响,如 AntD 和 next 版本兼容问题。
- Diffs for hydration errors:改善了 DEV 环境下 ssr 的错误提示。
- Cleanup functions for refs:19 给 ref 加上了清理函数,以前用 useEffect 清理,以后 ref 有自己的清理函数,组件卸载时 React 会执行该函数,并给出了示例代码。
- <Context> as a provider:以前 Context 使用需要三步(创建 Context、Provider 传递 value、后代组件消费 value),现在只需两步,可直接使用 Context 代替 Provider,Context.Provider 以后会被弃用,不过 React 会推出自动修改代码的工具。
- useDeferredValue 初始值:提及了 useDeferredValue 初始值相关内容。
- 其他支持:支持 Document Metadata、stylesheets、async scripts、preloading resources、更好的错误报告、自定义元素。在服务端渲染和客户端渲染中对自定义元素的 props 处理方式不同,服务端渲染中原始值或值为 true 的 props 呈现为 attributes,非原始 type 或值为 false 的 props 将被忽略;客户端渲染中与自定义元素实例上属性匹配的 props 将被分配为 properties,否则为 attributes。
五、综述
React19 改版较大,历经两年时间。总体上新特性围绕用户体验和开发体验提升,在用户体验方面有乐观、form 相关改进,开发体验上有 action 改进、流式布局进一步支持(服务端组件)、更人性化的写法(ref、Context)以及更丰富的支持(自定义原生、preload 等)。
扩展阅读
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有