Next.js中useFormState表单验证与数据传递问题
解决Next.js 14中useFormState客户端验证的参数传递问题
你的核心问题是对useFormState返回的formAction理解有误:它是一个无需手动传参的绑定函数,会自动收集当前表单的FormData并传递给服务器函数,不能像普通函数那样传参。同时,你错误地将验证函数设为了form的action属性,导致流程混乱。
下面是两种可行的解决方案:
方案一:在onSubmit事件中处理验证
将表单的action直接设为formAction,通过onSubmit事件拦截提交,先完成客户端验证,通过后再触发提交:
"use client"; import { useFormState } from "react-dom"; import farServerFunction from "./func.ts"; export default function Page() { const [formState, formAction] = useFormState(farServerFunction, null); const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 阻止默认提交行为 const formData = new FormData(e.currentTarget); const name = formData.get("name") as string; // 客户端验证 if (!name || name.length < 5) { alert("Name must be at least 5 characters long."); return; } // 验证通过,调用formAction提交 await formAction(); }; return ( <form action={formAction} onSubmit={handleSubmit}> <input type="text" name="name" /> <button type="submit">Submit</button> {/* 展示服务器返回的状态 */} {formState?.error && <p style={{ color: "red" }}>{formState.error}</p>} {formState?.message && <p>{formState.message}</p>} </form> ); }
方案二:整合验证与服务器函数
把客户端验证逻辑和服务器函数合并成一个函数,再传入useFormState,这样表单提交时会自动先执行验证,验证通过才会调用服务器函数,错误信息可以直接更新到formState中展示:
"use client"; import { useFormState } from "react-dom"; import farServerFunction from "./func.ts"; export default function Page() { // 整合验证与服务器调用的函数 const validateAndSubmit = async (formData: FormData) => { const name = formData.get("name") as string; if (!name || name.length < 5) { return { error: "Name must be at least 5 characters long." }; } // 验证通过,调用服务器函数 return farServerFunction(formData); }; const [formState, formAction] = useFormState(validateAndSubmit, null); return ( <form action={formAction}> <input type="text" name="name" /> <button type="submit">Submit</button> {/* 展示验证或服务器返回的错误 */} {formState?.error && <p style={{ color: "red" }}>{formState.error}</p>} {formState?.message && <p>{formState.message}</p>} </form> ); }
两种方案都能解决你的问题,方案二更符合Next.js表单状态管理的设计思路,不需要手动调用formAction,也能更友好地展示错误信息。
内容的提问来源于stack exchange,提问作者Pixtane
相关产品推荐
相关产品推荐

