介绍 React 19
前几日,React 发布了 React 19 RC 版本,带来了许多新功能和改进。本文主要来讲一下其中的 useActionState
hook,以及如何结合 Astro Actions 使用。
这里是 React 官方 关于 React 19 RC 的文章。
介绍 useActionState
useActionState
是 React 19 中引入的一个新 hook,用于简化处理表单提交和状态管理。它接受一个异步操作和默认值,并返回当前的状态、提交函数和加载状态。这个 hook 主要解决了在表单提交时的繁琐状态管理问题,使代码更加简洁和直观。
这里是 useActionState
的文档:useActionState reference。
没有 useActionState
之前
在引入 useActionState
之前,我们通常需要手动管理状态和异步操作。例如,处理一个简单的表单提交:
import { useState } from 'react';
function Form() {
const [name, setName] = useState('');
const [isPending, setIsPending] = useState(false);
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
setIsPending(true);
try {
const res = await fetch('/api/updateName', {
method: 'POST',
body: JSON.stringify({ name }),
});
const data = await res.json();
setResponse(data);
} catch (err) {
setError(err.message);
} finally {
setIsPending(false);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit" disabled={isPending}>Update</button>
{isPending && <p>Updating...</p>}
{error && <p>{error}</p>}
{response && <p>{response.message}</p>}
</form>
);
}
这段代码需要手动管理多个状态,并处理表单的提交逻辑。
使用 useActionState
有了 useActionState
,代码变得更为简洁。以下是使用 useActionState
的例子:
import { useActionState } from 'react';
function Form() {
const [state, submitAction, isPending] = useActionState(
async (name) => {
const res = await fetch('/api/updateName', {
method: 'POST',
body: JSON.stringify({ name }),
});
return res.json();
},
''
);
return (
<form action={submitAction}>
<input type="text" name="name" placeholder="name" />
<button type="submit" disabled={isPending}>Update</button>
{isPending && <p>Updating...</p>}
{state && <p>{state.message}</p>}
</form>
);
}
useActionState
接受一个异步操作和默认值,返回当前的状态、提交函数和加载状态。这样,我们只需要关注表单的提交逻辑,而不用手动管理多个状态。
结合 Astro Actions 使用 useActionState
Astro Actions 是 Astro 4.8 版本中新增的 API,用于在客户端类型安全地调用和定义后端函数。
并且在 @astrojs/react
集成中,提供了对 React 19 的支持。
这里是我往期介绍 Astro Actions 的文章:详解 Astro Actions API,在客户端类型安全地调用后端函数。
下面我们结合 Astro Actions 来使用 useActionState
。
在你的 Astro 项目中定义一个 actions/index.ts
文件:
import { defineAction, z } from "astro:actions";
export const server = {
updateName: defineAction({
accept: "form",
input: z.object({
name: z.string(),
}),
handler: async ({ name }) => {
console.log(`Received name: ${name}`);
return name;
},
}),
};
在 React 组件中引入 actions
import { useActionState } from "react"
import { experimental_withState } from "@astrojs/react/actions"
import { actions } from "astro:actions"
export function Form() {
const [state, submitAction, isPending] = useActionState(
experimental_withState(actions.updateName),
""
)
return (
<form action={submitAction}>
<input type="text" name="name" placeholder="name"/>
<button type="submit" disabled={isPending}>Update</button>
{state}
{isPending && <p>Updating...</p>}
</form>
)
}
@astrojs/react
提供了一个 experimental_withState
函数,用于将 Astro Actions 转换为 useActionState
可以使用的函数。
以上代码非常简洁,完成了一个前后端交互的表单提交功能,表单提交将直接调用 Astro Actions 中的 updateName
函数,状态自动管理。
总结
当然,上面写的都是很简单的例子,实际业务开发中可能会更复杂,并且 React 19 和 Astro Actions 都还在实验中,没有 stable,可能会有一些变化。
对于 useActionState
,我认为很适合结合 Server Actions 使用,包括 Astro Actions、React 的 Server Actions。
React 也一直在推进 RSC 和 Server Actions,通过类似的东西,让前后端开发更加简单,未来时代,或许快速出活才是王道。
最后,添加我微信 liruifengv2333,加群交流
- Astro 学习交流群
- 新生代程序员群
很高兴见到你,欢迎来玩儿~