Next.js表单提交成功后,如何携带ISBN参数重定向至编辑页面?
Next.js表单提交成功后,如何携带ISBN参数重定向至编辑页面?
我来帮你梳理下问题的根源,再给出最优的解决方案:
先分析你前两次尝试失败的原因
第一次尝试拿不到ISBN:你在
onSubmit里调用action(formData)时没有加await,所以response其实是一个未解析的Promise对象,自然拿不到里面的ISBN属性。这是异步调用里最容易忽略的小细节~第二次尝试用
redirect报错:大概率是你对Next.js Server Action里的redirect使用方式不对。Next.js的redirect是从next/navigation导入的,而且需要在标记了'use server'的Server Action中直接调用,不能先返回成功对象再调用——因为redirect本质是抛出一个重定向响应,会直接终止函数执行。
最优方案:Server Action端直接重定向(推荐)
这是最符合Next.js 13+ App Router架构的方式,逻辑都在服务器端处理,安全又标准:
步骤1:修正你的action.ts
确保它是Server Action,并且正确使用redirect:
'use server'; // 必须在文件顶部标记这是Server Action import { redirect } from 'next/navigation'; // 其他导入(比如Supabase、Schema等)... export async function action(formData: FormData) { const validatedFields = BookSchema.safeParse({ ISBN: formData.get("ISBN"), // 其他字段... }); if (!validatedFields.success) { console.error("Validation Errors:", validatedFields.error.format()); return { errors: validatedFields.error.flatten().fieldErrors, }; } const { ISBN } = validatedFields.data; const supabase = createClient(); const { error } = await supabase .from('books') .insert({ isbn: ISBN /* 其他字段 */ }); if (error) { return { error: true, message: error.message }; } // 插入成功后直接触发重定向,不需要返回任何对象 redirect(`/admin/books/${ISBN}/edit`); }
步骤2:修正onSubmit函数
加上await等待Server Action执行,同时处理错误提示:
async function onSubmit(data: BookInferSchema) { try { const formData = new FormData(); Object.entries(data).forEach(([key, value]) => { formData.append( key, value instanceof Date ? value.toISOString() : value.toString() ); }); // 关键:加上await解析Server Action的返回值 const response = await action(formData) as { error?: string; message?: string; }; if (response?.error) { toast({ title: "Error", description: `An error occurred: ${response.error}`, }); } // 重定向由Server Action处理,这里不需要额外逻辑 } catch { toast({ title: "Error", description: "An unexpected error occurred.", }); } }
备选方案:客户端端重定向(适合需要额外客户端逻辑的场景)
如果你需要在客户端做一些额外操作(比如复杂的弹窗提示、表单重置)后再跳转,可以用这个方式:
步骤1:action.ts返回ISBN
插入成功后把ISBN一起返回:
// ...插入成功后 return { error: false, message: 'Book added successfully', ISBN, };
步骤2:onSubmit中await并跳转
import { useRouter } from 'next/navigation'; // 导入路由 // 组件内获取router const router = useRouter(); async function onSubmit(data: BookInferSchema) { try { const formData = new FormData(); Object.entries(data).forEach(([key, value]) => { formData.append( key, value instanceof Date ? value.toISOString() : value.toString() ); }); // 必须加await const response = await action(formData) as { error?: string; message?: string; ISBN?: string; }; if (response?.error) { toast({ title: "Error", description: `An error occurred: ${response.error}`, }); } else if (response?.ISBN) { toast({ title: "Success", description: "Book added successfully!", }); form.reset(); // 直接客户端跳转 router.push(`/admin/books/${response.ISBN}/edit`); } } catch { toast({ title: "Error", description: "An unexpected error occurred.", }); } }
关于你第三次尝试的疑问
你用useEffect监听state再跳转的方式虽然能工作,但不够直观——因为跳转逻辑和表单提交的逻辑被拆分了,后续维护起来容易懵。更推荐直接在onSubmit里处理(不管是服务器端还是客户端方案),逻辑更连贯。
总结
- 优先选Server Action端重定向:符合Next.js架构,服务器端处理更安全、标准,用户体验也更好(HTTP层面的重定向)。
- 客户端重定向适合需要额外客户端交互的场景,但记得一定要
awaitServer Action的返回值。
备注:内容来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

