当前位置: 首页 > article >正文

Next.js v15 - 服务器操作以及调用原理

约定

服务器操作是在服务器上执行的异步函数。它们可以在服务器组件和客户端组件中调用,用于处理 Next.js 应用程序中的表单提交和数据修改。

服务器操作可以通过 React 的 “use server” 指令定义。你可以将该指令放在 async 函数的顶部以将该函数标记为服务器操作,或者放在单独文件的顶部以将该文件的所有导出标记为服务器操作。

export default function Page() {
  // 服务器操作
  async function create() {
    'use server'
    // 修改数据
  }
 
  return '...'
}
'use server'
 
export async function create() {}

应用

React 扩展了 HTML 元素,允许通过 action 属性调用服务器操作。

export default function Page() {
  async function createInvoice(formData: FormData) {
    'use server'
 
    const rawFormData = {
      customerId: formData.get('customerId'),
      amount: formData.get('amount'),
      status: formData.get('status'),
    }
 
    // 修改数据
    // 重新验证缓存
  }
 
  return <form action={createInvoice}>...</form>
}

通常,Next.js TypeScript 插件会标记updateItemAction,因为函数通常不能在客户端-服务器边界之间序列化,序列化是指将对象转换为可以存储或传输的格式。函数包含上下文和状态信息,无法简单地转化为可以在不同环境中执行的格式。

然而,名为 action 或以 Action 结尾的 props 被假定为接收服务器操作。 这只是一个启发式方法,因为 TypeScript 插件实际上并不知道它接收的是服务器操作还是普通函数。 运行时类型检查仍然会确保你不会意外地将函数传递给客户端组件。
处理表单时你可以将服务器操作与useActionState结合使用

export default function Page() {
const initialState: State = { message: null, errors: {} };
  const [state, formAction] = useActionState(createInvoice, initialState);
  async function createInvoice(prevState: State, formData: FormData) {
    'use server'
 
    const rawFormData = {
      customerId: formData.get('customerId'),
      amount: formData.get('amount'),
      status: formData.get('status'),
    }
 
    // 修改数据
    // 重新验证缓存
  }
 
  return <form action={formAction}>...</form>
}

传递另外参数
在这里插入图片描述
服务器操作将接收 userId 参数,以及表单数据:

'use server'
 
export async function updateUser(userId, formData) {}

程序化表单提交
你可以使用 requestSubmit() 方法以编程方式触发表单提交。例如,当用户使用 ⌘ + Enter 键盘快捷键提交表单时,你可以监听 onKeyDown 事件

'use client'
 
export function Entry() {
  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (
      (e.ctrlKey || e.metaKey) &&
      (e.key === 'Enter' || e.key === 'NumpadEnter')
    ) {
      e.preventDefault()
      e.currentTarget.form?.requestSubmit()
    }
  }
 
  return (
    <div>
      <textarea name="entry" rows={20} required onKeyDown={handleKeyDown} />
    </div>
  )
}

原理

每当你将 ‘use server’ 添加到服务器端函数并将其导入到客户端组件时,它都会将其标记为对客户端可用(服务器的入口点)。这并不意味着函数会被序列化并通过网络发送,相反,客户端将获得该函数的 URL 字符串,客户端可以使用它通过 RPC 向服务器发送请求。这是一个 POST 请求。这是自动为你处理的,你所要做的就是包含 ‘use server’,导入你的 server action 或将其作为 prop 传递,然后就使用它。您永远不会看到此 URL 字符串,但这就是它在后台的工作方式。

即使您在 server 组件中使用 server 操作,添加 “use server” 也很重要。假设您在服务器组件中有一个按钮,并且您希望在有人单击该按钮时使用服务器操作。您仍然需要一个 URL 字符串,因为该按钮最终会出现在客户端上,并点击该按钮。因此,只有当你在 server 操作中包含 “use server” 指令时,它才会起作用。

此外,如果你将服务器操作导入到客户端组件中,但忘记添加 “use server”,它会将该函数作为代码导入到客户端中。它将不再是服务器端功能。当你添加 “use server” 时,它会让该函数保留在服务器上。


http://www.kler.cn/a/446396.html

相关文章:

  • 渗透测试-前端加密分析之RSA加密登录(密钥来源服务器)
  • Linux shell脚本用于常见图片png、jpg、jpeg、tiff格式批量转webp格式后,并添加文本水印
  • 基于langchain的Agent(实现实时查询天气)
  • 【练习Day20】字符串变形
  • android RadioButton + ViewPager+fragment
  • C语言中的内存管理:理解指针、动态内存分配与内存泄漏
  • 搭建云手机平台的技术要求?
  • 无人机航测系统技术特点!
  • dolphinscheduler服务注册中心源码解析(二)基于zookeeper实现注册中心源码解析
  • 创建Copilot Agents 就像创建Word文档和PPT演示文稿一样简单
  • docker run 端口映射
  • 基于ceres优化的3d激光雷达开源算法
  • 【Unity3D】ILRuntime学习记录一
  • 面试题整理9----谈谈对k8s的理解2
  • vue2组件之间通信的四种方法总结
  • maven 中 有历史模块缓存 怎么清
  • vscode 版本升级导致yarn不能使用
  • vLLM项目加入PyTorch生态系统,引领LLM推理新纪元
  • “typedef“知识详解
  • Vue.js实例开发-如何通过Props传递数据
  • JDBC 入门教程
  • Ubuntu 上传项目到 GitHub
  • linux springboot项目启动端口被占用 Port 8901 was already in use.
  • Flink调优----资源配置调优与状态及Checkpoint调优
  • 【文档搜索引擎】使用多线程优化流程
  • React系列(八)——React进阶知识点拓展