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 排版

相关推荐
一 乐几秒前
个人博客|博客app|基于Springboot+微信小程序的个人博客app系统设计与实现(源码+数据库+文档)
java·前端·数据库·spring boot·后端·小程序·论文
LucianaiB23 分钟前
Qoder 降价,立即生效!首购 2 美金/月
后端
微学网络38 分钟前
基于 PVE 8.1 的 CentOS / Ubuntu / Docker / Kubernetes 部署手册
后端
nvvas44 分钟前
npm : 无法加载文件 D:\nvm\nodejs\npm.ps1,因为在此系统上禁止运行脚本问题解决
前端·npm·node.js
Main121381 小时前
JDK 8 Stream API 教程文档
后端
火山引擎开发者社区1 小时前
Vibe Coze-企业 AI 应用赛道开启
后端
百锦再1 小时前
大型省级政务平台采用金仓数据库(KingbaseES)
开发语言·数据库·后端·rust·eclipse
m0_639817151 小时前
基于springboot个人云盘管理系统【带源码和文档】
java·spring boot·后端
WangHappy1 小时前
Windows搭建MongoDB(4):服务器部署及远程访问
mongodb·mongoose
NUllPOINTEXCEPTION2 小时前
MyBatis-Plus 开发指北
后端