Next.js中Server Action如何做表单校验

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

通过之前的章学习,我们学习了Next.js强大的 Form 前后服务端交互功能Server Action。在HTML中我们对 Form 表单还有另一项常用的功能:表单校验。

如今的开发环境(前后分离),通常客户端需要做一次校验,服务端也需要做一次校验。但是往往很多时候客户端做了校验,服务端没有做校验,导致系统存在风险。在 Next.js 中我们可以做在Server Action做表单校验,并在客户端没有进行全局刷新的情况下更新页面。这个理念有点像远古的.net webFrom,真的是有点文艺复兴了,换句话来讲也能说明微软的思维不是我们一般人能理解,需要过 10 年后才知道微软的超前。

在 Next.js 我们可以在Server Action中做一次校验,就能完成客户端和服务端数据校验都要写两遍的尴尬问题,同时可以摆脱不必要的争吵。同时保障业务逻辑的安全性问题,如果对于比较敏感的数据校验也不用暴露在客户端中。(实际不应该暴露的,但为了赶进度很多时候很多后端都要求前端写在客户端中)。

如何进行 Server Validation 校验?

我们这里需要依赖一个第三方包zod,这个是一个强大的数据校验依赖包。不但可以用来校验 FromData 也能用来校验 Object 对象。

css 复制代码
npm install zod --save

我们接着之前的代码进行修改github.com/rexleimo/re...中添加以下代码

typescript 复制代码
"use server";
// ... some code
import { z } from "zod";

const schema = z.object({
  name: z.string().refine((v) => v.length === 0, {
    message: "图层名不能为空",
  }),
  desc: z.string(),
  images: z
    .string()
    .array()
    .refine((v) => v.length === 1, {
      message: "图册不能为空",
    }),
});

export async function ImageCreate(formData: FormData) {
  const formJson = Object.fromEntries(formData) as any;
  const images = (formJson.images as string).split(",");
  formJson.images = images;
  const parsed = schema.safeParse(formJson);

  if (parsed.success) {
    // some code...
  } else {
    // 校验失败的时候返回
    return { error: true, code: 1, message: parsed.error.errors };
  }
}

客户端中如何显示Error Message?

我们都知道Server Action中return的数据可以直接在客户端中获取到,所以我们可以修改github.com/rexleimo/re...

typescript 复制代码
// 这里只用name做演示
function page() {

    const [error, updateError] = useState<z.ZodIssue[]>([]);

    async function onSubmit(formData: FormData) {
        // 提交表单
        const { message, code } = await ImageCreate(formData);
        if (code == 1) {
            updateError(message!);
        }
    }

    const errorMessage = useCallback((name: string) => {
        return errorItem(name)?.message;
    }, [error]);

    const errorState = useCallback((name: string) => {
        return errorItem(name) ? 'error' : 'none'
    }, [error]);

    const errorItem = useCallback((name: string) => {
        if (error) {
            return error.find(v => v.path.includes('name'))
        }
        return undefined
    }, [error])

    return (
        <Layout>
            <form className='!w-full' action={onSubmit}>
                <FeiId label={'图集名称'}
                    validationState={errorState('name')}
                    validationMessage={errorMessage('name')}>
                    <Input id={'name'} name='name' type='text' placeholder='图集名称' />
                </FeiId>
                {/* some codeing */}
            </form>
        </Layout >
    )
}

export default page

看到这样的效果我们就已经完成任务。

结合Form的Input的name来做一些数据的联动会不会比Antd的那种Js上下文Context有了不一样的思路呢?如果有可以给梦兽编程一个三连支持一下哦!你的三连是我做视频最大的动力。

感谢你的阅读,期待在下一篇文章Next.js 上传文件中再次见到你!

这里是梦兽编程,本次的代码更新将会放在Github本次项目的Github连接中的V3.0分支中

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

本文使用 markdown.com.cn 排版

相关推荐
IT_陈寒1 小时前
Vue的双向绑定把我坑惨了,原来这个场景不能用
前端·人工智能·后端
烬羽1 小时前
从 nest new 到 Hello World:一个最小 NestJS 项目,讲透工厂 + 装饰器 + 模块化
设计模式·node.js·nestjs
默_笙2 小时前
❗ 点击计数按钮,为什么"峨眉队"也跟着重新渲染?React.memo 说:我记住了
前端·javascript
31535669132 小时前
DeepSeek Harness 发布后,我没急着跑 Demo,先把 `.agents/` 翻了一遍
前端·后端·github
名字还没想好☜2 小时前
Next.js 用 Server Components 直连数据库:去掉 API 层的边界,和三条别踩的安全红线
前端·javascript·数据库·安全·react·next.js
Nturmoils2 小时前
不在公司,也能连回办公电脑:用 Natapp 打通 Windows 远程桌面
后端
LEE3 小时前
AI Agent 都在疯狂加功能,它说:我全砍了
前端·后端
桦说编程3 小时前
记一次 Coding Agent 改动带来的bug与启示
后端·agent·vibecoding
302wanger3 小时前
Mole-在终端里给Mac做减法
后端
一心只读圣贤书3 小时前
本地后端环境与前端联调总结(前端小白视角)
后端