Next.js13实战开发,在服务端组件中使用Forms表单超方便的前后交互

如果想看专栏的方式可以点击进入Next图册目实践

通过之前的分享,我们已经知道Form表单提交可以在app/api/route.ts使用handle的方式进行处理。

但其实Next.js13 App Router中提供了一种使用服务器操作处理表单提交和数据更改的强大方法。

服务器操作的工作原理

使用服务器操作,无需手动创建 API 终结点。相反,您可以定义可以直接从组件调用的异步服务器函数。

服务器操作可以在服务器组件中定义,也可以从客户端组件调用。在服务器组件中定义操作允许表单在没有 JavaScript 的情况下运行,从而提供渐进式增强。

简单点来说你可以在use client中直接调用服务端的方法,它可以区分你是服务端方法还是客户端方法!是不突然就感觉很逆天了?

要使用这个特性我们首先需要在next.config.js文件中启动服务器的操作

java 复制代码
module.exports = {
  experimental: {
    serverActions: true,
  },
}

要点需知:

  • 从服务端组件调用服务器操作的表单可以在没有 JavaScript (浏览器客户端) 的情况下运行。
  • 如果 JavaScript 尚未加载,则从客户端组件调用服务器操作的表单将对提交进行排队,从而优先考虑客户端冻结。(客户出现UI线程阻塞)
  • 服务器操作继承它们所用页面或布局的运行时。
  • 现在的版本如果路由使用serverActions,必须要动态呈现。

serverActions在操作的过程中,是不会整个页面提交的。Next.js内部回知道你想返回什么内容。具体内容可以细看Form中的错误例子。

如何使用?

serverActions,请在服务端组件中定义serverActions。操作可以与函数内第一行定义,也可以在文件顶部具有 use server 指令的单独文件中定义。

javascript 复制代码
export default function Page() {
  async function create(formData: FormData) {
    'use server'
 
    // mutate data
    // revalidate cache
  }
  // 这里的action不在写 url地址 可以直接填写方法
  return <form action={create}>...</form> 
}

当然你也可以写出这种方式

javascript 复制代码
// app/actions.ts
 'use server'
export default async function create(formData: FormData) {
    // mutate data
    // revalidate cache
}

// app/page.tsx
import create from '@/app/actions'
export default function Page() {
  // 这里的action不在写 url地址 可以直接填写方法
  return <form action={create}>...</form> 
}

表单校验

对于一个web应用开发来说,From组件的数据校验是必不可少的。我们建议使用 HTML 验证,就像 required 和 进行 type="email" 基本表单验证一样。

对于更高级的服务器端验证,梦兽编程这里使用zod进行表单的校验,相比于route.ts的handle 可以少写一步代码。

ini 复制代码
req.fromData().then(values=>{})
javascript 复制代码
import { z } from 'zod'
 
const schema = z.object({
  // ...
})
 
export default async function submit(formData: FormData) {
  const parsed = schema.parse({
    id: formData.get('id'),
  })
  // ...
}

提交的状态怎么做呢?

这里需要用到react-dom的一些api,

javascript 复制代码
'use client'
 
import { experimental_useFormStatus as useFormStatus } from 'react-dom'
 
function SubmitButton() {
  const { pending } = useFormStatus()
 
  return (
    <button disabled={pending}>{pending ? 'Submitting...' : 'Submit'}</button>
  )
}

From的错误状态处理

javascript 复制代码
'use server'
 
export async function create(formData: FormData) {
  try {
    await createItem(formData.get('item'))
    revalidatePath('/')
    return { message: 'Success!' }
  } catch (e) {
    return { message: 'There was an error.' }
  }
}

我们依然可以返回json格式,回顾上面所说,我们在客户端组件中就可以直接获取操作,前方高能的前后端RPC通信

javascript 复制代码
'use client'
 
import { create } from './actions'
import { useState } from 'react'
 
export default function Page() {
  const [message, setMessage] = useState<string>('')
 
  async function onCreate(formData: FormData) {
    const res = await create(formData)
    //是不是很方便呢?这不比TRPC方便?
    setMessage(res.message)
  }
 
  return (
    <form action={onCreate}>
      <input type="text" name="item" />
      <button type="submit">Add</button>
      <p>{message}</p>
    </form>
  )
}

其他

其他关于 headers cookie 等操作和Node.js,Next.js中route的handle操作类似。也是web常用技巧,这里就不展开说了,感兴趣的可以回去观看之前的内容。

感谢你的阅读,期待在下一篇文章中再次见到你!

我的B站视频号更多视频动态。

本文使用 markdown.com.cn 排版

相关推荐
wgc2k2 小时前
Node.js游戏服务器项目移植-2: 用TypeScript还是Javascript
服务器·游戏·node.js
llz_1123 小时前
web-第二次课后作业
前端·后端·web
红尘散仙8 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
卷毛的技术笔记10 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
会编程的土豆10 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
喵个咪10 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
basketball61611 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
qq_25183645711 小时前
SpringBoot+Vue 共享电池柜管理系统 完整实现 前后端分离项目实战 完整代码
vue.js·spring boot·后端
zhangxingchao11 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
IT_陈寒12 小时前
Vite打包时遇到的坑,原来问题出在这里
前端·人工智能·后端