学习 React 19 新 Hook useActionState,并在 Astro 中使用
发布于:2024年6月26日

字数:854 字

阅读时间:4 分钟

介绍 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 文件:

src/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 学习交流群
关注公众号 SayHub,带来更多原创内容。
很高兴见到你,欢迎来玩儿~