You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js表单提交成功后,如何携带ISBN参数重定向至编辑页面?

Next.js表单提交成功后,如何携带ISBN参数重定向至编辑页面?

我来帮你梳理下问题的根源,再给出最优的解决方案:

先分析你前两次尝试失败的原因

  1. 第一次尝试拿不到ISBN:你在onSubmit里调用action(formData)时没有加await,所以response其实是一个未解析的Promise对象,自然拿不到里面的ISBN属性。这是异步调用里最容易忽略的小细节~

  2. 第二次尝试用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层面的重定向)。
  • 客户端重定向适合需要额外客户端交互的场景,但记得一定要await Server Action的返回值。

备注:内容来源于stack exchange,提问作者JS3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 18:55:27