React Canary 在X平台宣布支持 Server Action

1.React Canary 宣布支持 Server Action

2023 年 10 月 24 日 React 团队宣布 Server Action 已经集成到 React Canary 中,可供框架和库采用。

Server Action 是与在服务器上运行的组件一起创建的函数,用于执行数据突变等任务。

关于 React 的版本信息需要注意以下三个:

  • Latest:稳定的 semver React 版本,即从 npm 安装 React 时得到的。
  • Canary: 跟踪 React 源代码存储库的主要分支,将这些视为下一个 semver 版本的候选版本。 框架等可以选择将此通道与固定版本的 React 一起使用。 还可以使用 Canary 进行 React 和第三方项目之间的集成测试。
  • Experimental:包括稳定版本中不可用的实验性 API 和功能。 它们还跟踪主分支,但打开了附加功能标志。 使用此功能可以在发布之前试用即将推出的功能。

2.使用'use server'声明 Server Action

在 async 函数体的顶部添加“use server”以将该函数标记为可由客户端直接调用,该功能称为 Server Action。

async function addToCart(data) {
  'use server';
  // 声明Server Action
}

当在客户端上调用 Server Action 时,其将向服务器发出网络请求,其中包括传递参数的序列化副本。 如果 Server Action 返回一个值,则该值将被序列化并返回给客户端。

开发者也可以将指令添加到文件顶部,将该文件中的所有导出标记为可在任何地方使用的 Server Action,包括:在客户端代码中导入,而不是单独使用“use server”标记函数。

3.Server Action 注意事项

关于 Server Action 有以下内容需要了解:

  • “use server”必须位于函数、模块的最开头, 高于任何其他代码,包括导入。 同时,必须用单引号或双引号编写,而不是反引号
  • 'use server' 只能在服务器端文件中使用,生成的 Server Action 可以通过 props 传递给客户端组件。
  • 从客户端代码导入 Server Action,必须在模块级别使用该指令
  • 由于底层调用始终是异步的,因此“use server”只能在异步函数上使用。
  • 始终将 Server Action 的参数视为不受信任的输入并授权更改。同时,保证参数和返回值始终可序列化,避免类似:React 元素、JSX、Class、Functions、未全局注册的 Symbols 等等数据格式。
  • 应在 Transition 中调用 Server Action, 传递给
    或 formAction 的 Server Action 将在 Transition 中自动调用。
  • Server Action 是为更新服务器端状态的突变而设计的,不建议用于数据获取,同时注意如登录权限控制。 因此,实现 Server Action 的框架通常一次处理一个操作,并且没有办法缓存返回值

4.如何使用 Server Action

4.1 表单中使用 Server Action

Server Action 最常见的用例是调用改变数据的服务器函数。 在浏览器上,HTML 表单元素是用户提交变更的传统方法。 通过 React Server Components,React 引入了对表单中 Server Action 的一流支持。

下面是一个允许用户请求用户名的表单:

// App.js
async function requestUsername(formData) {
  'use server';
  const username = formData.get('username');
  // ...
}

export default App() {
  
    
    
  
}

在上面示例中,requestUsername 是传递给

的 Server Action。 当用户提交此表单时,就会向服务器函数 requestUsername 发出网络请求。 当在表单中调用 Server Action 时,React 将提供表单的 FormData 作为 Server Action 的第一个参数。

通过将 Server Action 传递给表单操作,React 可以逐步增强表单,甚至意味着可以在加载 JavaScript 包之前提交表单。

4.2 处理表单中的返回值

在用户名请求表单中,用户名可能不可用。 requestUsername 应该告诉用户是否失败。

要根据 Server Action 的结果更新 UI,同时支持渐进增强,此时可以使用 useFormState。

// requestUsername.js
'use server';
// 服务端导出Action
export default async function requestUsername(formData) {
  const username = formData.get('username');
  if (canRequest(username)) {
    // 权限控制
    return 'successful';
  }
  return 'failed';
}
// UsernameForm.js
'use client';
import { useFormState } from 'react-dom';
import requestUsername from './requestUsername';
function UsernameForm() {
  const [returnValue, action] = useFormState(requestUsername, 'n/a');
  //  客户端通过useFormState调用
  return (
    <>
      
        
        
      
      

Last submission request returned: {returnValue}

); }

请注意,与大多数 Hook 一样,useFormState 只能在客户端代码中调用

4.3 在 form 之外调用 Server Action

Server Action 是公开的服务器端点,可以在客户端代码中的任何位置调用。

在表单外部使用 Server Action 时,可以在 Transition 中调用。其允许开发者显示加载指示器、显示状态更新并处理意外错误, 表单将自动将 Server Action 包装在 Transition 中。

import incrementLike from './actions';
import { useState, useTransition } from 'react';

function LikeButton() {
  const [isPending, startTransition] = useTransition();
  const [likeCount, setLikeCount] = useState(0);

  const onClick = () => {
    startTransition(async () => {
      const currentCount = await incrementLike();
      // 读取 Server Action 返回值需要 await
      setLikeCount(currentCount);
    });
  };

  return (
    <>
      

Total Likes: {likeCount}

; ); }
// actions.js
'use server';
let likeCount = 0;
// Server Action方法
export default async incrementLike() {
  likeCount++;
  return likeCount;
}

要读取 Server Action 返回值,需要 await 返回的 Promise。

参考资料

https://twitter.com/reactjs/status/1716573234160967762/photo/1

https://react.dev/reference/react/use-server

https://react.dev/community/versioning-policy

https://react.dev/blog/2023/05/03/react-canaries

原文链接:,转发请注明来源!