React 19 测试版发布,时隔两年终于更新了

本文主要是介绍React 19 测试版发布,时隔两年终于更新了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

众所周知,前端开发这个领域日新月异,每隔一段时间就会整出一点新玩意,被戏称做“前端娱乐圈”,圈子里大佬一个比一个卷,都在疯狂的造轮子。

然而有这么一位选手,自从 2022 年 6 月发布了最后一次稳定版本后,就一直没有再发布新的版本,它就是大名鼎鼎的前端三大框架之一 React。

就在昨日,时隔将近两年,React 突然宣布,React 19 测试版现已在 npm 上发布,随之而来的还有 React 18.3.0 稳定版。

下面让我们一起来看看 React 19 测试版有什么新特性吧!

React 19 的新特性

Actions

在 React 应用中,执行数据变更然后更新状态是一个常见的用例。例如,当用户提交表单来更改他们的名字时,你将发起一个 API 请求,然后处理响应。在过去,你需要手动处理待处理状态、错误、乐观更新和顺序请求。

例如,你可以在 useState 中处理待处理和错误状态:

// 动作之前
function UpdateName({}) {const [name, setName] = useState(" ");const [error, setError] = useState(null);const [isPending, setIsPending] = useState(false);const handleSubmit = async () => {setIsPending(true);const error = await updateName(name);setIsPending(false);if (error) {setError(error);return;} redirect("/path");};return (<div><input value={name} onChange={(event) => setName(event.target.value)} /><button onClick={handleSubmit} disabled={isPending}>更新</button>{error && <p>{error}</p>}</div>);
}

在 React 19 中,我们增加了对在转换中使用异步函数以自动处理待处理状态、错误、表单和乐观更新的支持。

例如,你可以使用 useTransition 来为你处理待处理状态:

// 使用动作中的待处理状态
function UpdateName({}) {const [name, setName] = useState(" ");const [error, setError] = useState(null);const [isPending, startTransition] = useTransition();const handleSubmit = async () => {startTransition(async () => {const error = await updateName(name);if (error) {setError(error);return;} redirect("/path");})};return (<div><input value={name} onChange={(event) => setName(event.target.value)} /><button onClick={handleSubmit} disabled={isPending}>更新</button>{error && <p>{error}</p>}</div>);
}

异步转换将立即将 isPending 状态设置为 true,发起异步请求,并在任何转换后将 isPending 设置为 false。这允许你在数据变更时保持当前 UI 的响应性和交互性。

按照惯例,使用异步转换的函数被称为 Actions。Actions 自动为你提交数据:

  • 待处理状态:动作提供了一个从请求开始就启动的待处理状态,并在最终状态更新提交时自动重置。
  • 乐观更新:动作支持新的 useOptimistic 钩子,因此在请求提交时你可以向用户显示即时反馈。
  • 错误处理:动作提供错误处理,因此当请求失败时,你可以显示错误边界,并自动将乐观更新回退到它们的原始值。
  • 表单<form> 元素现在支持将函数传递给 actionformAction 属性。将函数传递给 action 属性默认使用动作,并在提交后自动重置表单。

在 Actions 的基础上,React 19 引入了 useOptimistic 来管理乐观更新,以及一个新的钩子 React.useActionState 来处理动作的常见情况。在 react-dom 中,我们增加了 <form> 动作来自动管理表单和 useFormStatus 来支持表单中动作的常见情况。

在 React 19 中,上述示例可以简化为:

// 使用 <form> 动作和 useActionState
function ChangeName({ name, setName }) {const [error, submitAction, isPending] = useActionState(async (previousState, formData) => {const error = await updateName(formData.get("name"));if (error) {return error;}redirect("/path");});return (<form action={submitAction}><input type="text" name="name" /><button type="submit" disabled={isPending}>更新</button>{error && <p>{error}</p>}</form>);
}

在下一节中,我们将分解 React 19 中每个新动作特性的细节。

新钩子:useActionState

为了使动作的常见情况更容易,我们添加了一个名为 useActionState 的新钩子:

const [error, submitAction, isPending] = useActionState(async (previousState, newName) => {const {error} = await updateName(newName);if (!error) {// 你可以返回动作的任何结果。// 在这里,我们只返回错误。return error;}// 处理成功
});

useActionState 接受一个函数(“动作”),并返回一个包装后的动作来调用。这是因为动作可以组合。当包装后的动作被调用时,useActionState 将返回动作的最后一个结果作为 data,并将动作的待处理状态作为 pending

React.useActionState 之前在 Canary 版本中被称为 ReactDOM.useFormState,但我们已经重命名了它并弃用了 useFormState

React DOM:<form> 动作

动作还与 React 19 的新 <form> 特性集成,用于 react-dom。我们增加了支持将函数作为 <form><input><button> 元素的 actionformAction 属性传递,以自动使用动作提交表单:

<form action={actionFunction}>

<form> 动作成功时,React 将自动为非受控组件重置表单。如果你需要手动重置 <form>,你可以调用新的 requestFormReset React DOM API。

React DOM:新钩子:useFormStatus

在设计系统中,编写需要访问其所在的 <form> 的信息的设计组件是很常见的,而不需要将属性钻取到组件中。这可以通过上下文完成,但为了使常见情况更容易,我们添加了一个新的钩子 useFormStatus

import {useFormStatus} from 'react-dom';function DesignButton() {const {pending} = useFormStatus();return <button type="submit" disabled={pending} />
}

useFormStatus 读取父 <form> 的状态,就像表单是一个上下文提供者一样。

新钩子:useOptimistic

执行数据变更时,另一个常见的 UI 模式是在异步请求进行中乐观地显示最终状态。在 React 19 中,我们添加了一个新的钩子 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>你的姓名是:{optimisticName}</p><p><label>更改姓名:</label><inputtype="text"name="name"disabled={currentName !== optimisticName}/></p></form>);
}

useOptimistic 钩子将在 updateName 请求进行中时立即渲染 optimisticName。当更新完成或出现错误时,React 将自动切换回 currentName 值。

新 API:use

在 React 19 中,我们引入了一个新的 API 来在渲染时读取资源:use

例如,你可以使用 use 读取一个 promise,React 将会在 promise 解决之前挂起:

import {use} from 'react';function Comments({commentsPromise}) {// `use` 将会在 promise 解决之前挂起。const comments = use(commentsPromise);return comments.map(comment => <p key={comment.id}>{comment}</p>);
}function Page({commentsPromise}) {// 当 `use` 在 Comments 中挂起时,// 这个 Suspense 边界将会被显示。return (<Suspense fallback={<div>Loading...</div>}><Comments commentsPromise={commentsPromise} /></Suspense>)
}

use 不支持在渲染中创建的 promises,如果你尝试将一个在渲染中创建的 promise 传递给 use,React 将会警告:

一个组件被一个未缓存的 promise 挂起了。在客户端组件或钩子中创建 promises 目前还不支持,除非是通过一个与 Suspense 兼容的库或框架。

要修复这个问题,你需要从支持缓存的 suspense 驱动的库或框架中传递一个 promise。在未来,我们计划推出一些功能,使在渲染中缓存 promises 更加容易。

你也可以使用 use 读取上下文,允许你有条件地读取 Context,例如在提前返回之后:

import {use} from 'react';
import ThemeContext from './ThemeContext'function Heading({children}) {if (children == null) {return null;}// 这在 useContext 中是行不通的// 因为提前返回了。const theme = use(ThemeContext);return (<h1 style={{color: theme.color}}>{children}</h1>);
}

use API 只能在渲染中调用,类似于钩子。与钩子不同,use 可以有条件地被调用。在未来,我们计划支持更多在渲染中使用资源的方式与 use

React 服务器组件

服务器组件

服务器组件是一个新的选项,允许在与您的客户端应用程序或服务器端渲染(SSR)服务器不同的环境提前进行组件渲染,即在构建之前进行渲染。这个独立的环境就是 React 服务器组件中的“服务器”。服务器组件可以在您的 CI 服务器上构建时运行一次,或者它们可以针对每个请求使用 Web 服务器运行。

React 19 包含了 Canary 频道中包含的所有 React 服务器组件特性。这意味着带有服务器组件的库现在可以将 React 19 作为具有 react-server 导出条件的同级依赖,用于支持全栈 React 架构的框架。

虽然 React 19 中的 React 服务器组件是稳定的,并且在主要版本之间不会破坏,但用于实现 React 服务器组件打包器或框架的底层 API 不遵循 semver,并且在 React 19.x 的次要版本之间可能会破坏。

要作为打包器或框架支持 React 服务器组件,我们建议固定到特定的 React 版本,或使用 Canary 版本。我们将继续与打包器和框架合作,以在未来稳定用于实现 React 服务器组件的 API。

服务器 Actions

服务器 Actions 允许客户端组件调用在服务器上执行的异步函数。

当一个服务器 Actions 被定义为带有 "use server" 指令时,您的框架将自动创建对服务器函数的引用,并将该引用传递给客户端组件。当客户端上调用该函数时,React 会向服务器发送一个请求以执行该函数,并返回结果。

一个常见的误解是服务器组件由 "use server" 表示,但实际上没有用于服务器组件的指令。"use server" 指令用于服务器操作。

服务器 Actions 可以在服务器组件中创建,并作为属性传递给客户端组件,或者它们可以被导入并在客户端组件中使用。

有关更多 React 19 的改进功能,请参阅 React 官方博客原文:https://react.dev/blog/2024/04/25/react-19

这篇关于React 19 测试版发布,时隔两年终于更新了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/938710

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/