行动
react 应用程序中的一个常见用例是执行数据突变,然后更新状态作为响应。例如,当用户提交表单以更改其姓名时,您将发出 api 请求,然后处理响应。过去,您需要手动处理挂起状态、错误、乐观更新和顺序请求。
例如,您可以在 usestate 中处理挂起和错误状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// before actions
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}>
update
</button>
{error && <p>{error}</p>}
</div>
);
}
在 react 19 中,我们添加了对在转换中使用异步函数的支持,以自动处理挂起状态、错误、表单和乐观更新。
例如,您可以使用 usetransition 为您处理挂起状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// using pending state from actions
function updatename({}) {
const [name, setname] = usestate("");
const [error, seterror] = usestate(null);
const [ispending, starttransition] = usetransition();
const handlesubmit = () => {
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}>
update
</button>
{error && <p>{error}</p>}
</div>
);
}
异步转换将立即将 ispending 状态设置为 true,发出异步请求,并在任何转换后将 ispending 切换为 false。这使您可以在数据更改时保持当前 ui 的响应能力和交互性。
笔记
按照惯例,使用异步转换的函数称为“操作”。
操作会自动为您管理提交数据:挂起状态:操作提供一个挂起状态,该状态在请求开始时启动,并在提交最终状态更新时自动重置。
乐观更新:操作支持新的 useoptimistic 挂钩,因此您可以在提交请求时向用户显示即时反馈。
错误处理:操作提供错误处理,以便您可以在请求失败时显示错误边界,并自动将乐观更新恢复为其原始值。
表单: 元素现在支持将函数传递给 action 和 formaction 属性。将函数传递给操作属性默认使用操作,并在提交后自动重置表单。基于 actions 构建,react 19 引入了 useoptimistic 来管理乐观更新,并引入了一个新的钩子 react.useactionstate 来处理 actions 的常见情况。在react-dom中,我们添加了
actions来自动管理表单,并使用formstatus来支持表单中actions的常见情况。在 react 19 中,上面的例子可以简化为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// using <form> actions and 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 null;
},
null,
);
return (
<form action={submitaction}>
<input type="text" name="name" />
<button type="submit" disabled={ispending}>update</button>
{error && <p>{error}</p>}
</form>
);
}
在下一节中,我们将详细介绍 react 19 中的每个新 action 功能。
新钩子:useactionstate
为了使操作的常见情况更容易,我们添加了一个名为 useactionstate 的新钩子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const [error, submitaction, ispending] = useactionstate(
async (previousstate, newname) => {
const error = await updatename(newname);
if (error) {
// you can return any result of the action.
// here, we return only the error.
return error;
}
// handle success
return null;
},
null,
);
useactionstate 接受一个函数(“action”),并返回一个包装的 action 来调用。这是有效的,因为动作是组合的。当调用被包装的 action 时,useactionstate 会返回该 action 的最后结果作为数据,并将该 action 的挂起状态作为挂起。
笔记
react.useactionstate 以前在 canary 版本中称为 reactdom.useformstate,但我们已重命名它并弃用了 useformstate。
请参阅#28491 了解更多信息。
有关更多信息,请参阅 useactionstate 的文档。react dom:
操作actions 还与 react 19 的 react-dom 的新
功能集成。我们添加了对传递函数作为 、 和 元素的 action 和 formaction 属性的支持,以使用 actions 自动提交表单:
1
<form action={actionfunction}>
当
action 成功时,react 会自动重置不受控制组件的表单。如果您需要手动重置 ,可以调用新的 requestformreset react dom api。有关更多信息,请参阅
、 和 的 react-dom 文档。react dom:新挂钩:useformstatus
在设计系统中,通常会编写需要访问其所在
信息的设计组件,而无需将 props 深入到组件。这可以通过 context 来完成,但为了使常见情况更容易,我们添加了一个新的钩子 useformstatus:
1
2
3
4
5
6
import {useformstatus} from react-dom;
function designbutton() {
const {pending} = useformstatus();
return <button type="submit" disabled={pending} />
}
useformstatus 读取父级
的状态,就好像表单是上下文提供者一样。有关更多信息,请参阅 useformstatus 的 react-dom 文档。
新钩子:useoptimistic
执行数据突变时的另一种常见 ui 模式是在异步请求正在进行时乐观地显示最终状态。在 react 19 中,我们添加了一个名为 useoptimistic 的新钩子,以简化此操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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>
);
}
useoptimistic 钩子将在 updatename 请求正在进行时立即渲染 optimisticname。当更新完成或出错时,react 会自动切换回 currentname 值。
有关更多信息,请参阅 useoptimistic 的文档。
新api:使用
在 react 19 中,我们引入了一个新的 api 来读取渲染中的资源:use。
例如,您可以使用 use 来读取 promise,react 将 suspend 直到 promise 解决:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import {use} from react;
function comments({commentspromise}) {
// `use` will suspend until the promise resolves.
const comments = use(commentspromise);
return comments.map(comment => <p key={comment.id}>{comment}</p>);
}
function page({commentspromise}) {
// when `use` suspends in comments,
// this suspense boundary will be shown.
return (
<suspense fallback={<div>loading...</div>}>
<comments commentspromise={commentspromise} />
</suspense>
)
}
笔记
use 不支持渲染中创建的 promise。
如果你尝试传递在渲染中创建的 promise 来使用,react 会发出警告:
1
2
3
4
error
a component was suspended by an uncached promise. creating promises
inside a client component or hook is not yet supported, except via a
suspense-compatible library or framework.
要修复此问题,您需要从支持缓存 promise 的 suspense 支持的库或框架传递 promise。将来,我们计划发布一些功能,以便更轻松地在渲染中缓存 promise。
您还可以使用 use 来读取上下文,允许您有条件地读取上下文,例如在提前返回后:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import {use} from react;
import themecontext from ./themecontext
function heading({children}) {
if (children == null) {
return null;
}
// this would not work with usecontext
// because of the early return.
const theme = use(themecontext);
return (
<h1 style={{color: theme.color}}>
{children}
</h1>
);
}
use api只能在render中调用,类似于hooks。与钩子不同,use 可以有条件地调用。未来我们计划支持更多在渲染和使用中消耗资源的方式。
更多信息请参阅使用文档。
新的 react dom 静态 api
我们在react-dom/static中添加了两个新的api来生成静态站点:
预渲染 prerendertonodestream这些新 api 通过等待数据加载以生成静态 html 来改进 rendertostring。它们旨在与 node.js streams 和 web streams 等流环境配合使用。例如,在 web stream 环境中,您可以使用 prerender 将 react 树预渲染为静态 html:
1
2
3
4
5
6
7
8
9
10
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 },
});
}
预渲染 api 将等待所有数据加载,然后返回静态 html 流。流可以转换为字符串,或与流响应一起发送。他们不支持加载流媒体内容,这是
反应服务器组件
服务器组件
服务器组件是一个新选项,允许在捆绑之前在与客户端应用程序或 ssr 服务器分开的环境中提前渲染组件。这个单独的环境是 react server components 中的“服务器”。服务器组件可以在构建时在 ci 服务器上运行一次,也可以使用 web 服务器针对每个请求运行。
react 19 包含 canary 通道中包含的所有 react server 组件功能。这意味着随服务器组件一起提供的库现在可以将 react 19 作为对等依赖项,并具有反应服务器导出条件,以便在支持全栈 react 架构的框架中使用。
以上就是React 19 中的新增功能的详细内容,更多请关注php中文网其它相关文章!