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

Next.js 13.4.12中Server Action报错backingFormData.forEach is not a function求助

问题:Next.js 13.4.12 Server Action提交表单报错"backingFormData.forEach is not a function"

错误信息

报错截图
报错内容:backingFormData.forEach is not a function

相关代码片段

表单代码

<form className="" action={handleFormAction}>
  <div className="flex flex-col space-y-4">
    <div className="flex flex-col space-y-2">
      <label htmlFor="email">Email</label>
      <input
        className="border border-gray-300 rounded-md px-4 py-2"
        type="email"
        name="email"
        id="email"
      />
    </div>

    <div className="flex flex-col space-y-2">
      <label htmlFor="password">Password</label>
      <input
        className="border border-gray-300 rounded-md px-4 py-2"
        type="password"
        name="password"
        id="password"
      />
    </div>

    <button
      className="bg-blue-500 text-white rounded-md px-4 py-2"
      type="submit"
    >
      Login
    </button>
  </div>
</form>

服务端函数(原组件内定义)

async function handleFormAction(formData: FormData) {
  "use server";

  const name = formData.get("name");
  // do something
}

package.json

{
  "name": "server-action",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@prisma/client": "^5.0.0",
    "@types/node": "20.4.4",
    "@types/react": "18.2.16",
    "@types/react-dom": "18.2.7",
    "autoprefixer": "10.4.14",
    "eslint": "8.45.0",
    "eslint-config-next": "13.4.12",
    "next": "13.4.12",
    "postcss": "8.4.27",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.3",
    "typescript": "5.1.6"
  }
}

完整原代码

import Image from "next/image";

export default function Home() {
  async function handleFormAction(formData: FormData) {
    "use server";

    const name = formData.get("name");
    // do something
  }
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <header>
        <h2>Login FUllstack</h2>
      </header>

      <form className="" action={handleFormAction}>
        <div className="flex flex-col space-y-4">
          <div className="flex flex-col space-y-2">
            <label htmlFor="email">Email</label>
            <input
              className="border border-gray-300 rounded-md px-4 py-2"
              type="email"
              name="email"
              id="email"
            />
          </div>

          <div className="flex flex-col space-y-2">
            <label htmlFor="password">Password</label>
            <input
              className="border border-gray-300 rounded-md px-4 py-2"
              type="password"
              name="password"
              id="password"
            />
          </div>

          <button
            className="bg-blue-500 text-white rounded-md px-4 py-2"
            type="submit"
          >
            Login
          </button>
        </div>
      </form>
    </main>
  );
}

原因分析

这个错误是Next.js 13.4.12版本的已知限制:Server Action不能直接定义在React组件内部。当你在组件内定义handleFormAction时,Next.js无法正确处理FormData的序列化与传递,导致内部的backingFormData不是一个标准的可遍历FormData对象,从而抛出forEach is not a function的错误。

解决方法

方法1:将Server Action提取到单独文件中

这是13.4.12版本下的标准解决方案:

  1. 在app目录下创建actions.ts文件:
// app/actions.ts
"use server";

export async function handleFormAction(formData: FormData) {
  const email = formData.get("email");
  const password = formData.get("password");
  // 执行你的业务逻辑,比如验证、数据库操作等
  console.log("Received form data:", email, password);
}
  1. 在Home组件中导入并使用这个函数:
// app/page.tsx
import Image from "next/image";
import { handleFormAction } from "./actions";

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <header>
        <h2>Login FUllstack</h2>
      </header>

      <form className="" action={handleFormAction}>
        <div className="flex flex-col space-y-4">
          <div className="flex flex-col space-y-2">
            <label htmlFor="email">Email</label>
            <input
              className="border border-gray-300 rounded-md px-4 py-2"
              type="email"
              name="email"
              id="email"
            />
          </div>

          <div className="flex flex-col space-y-2">
            <label htmlFor="password">Password</label>
            <input
              className="border border-gray-300 rounded-md px-4 py-2"
              type="password"
              name="password"
              id="password"
            />
          </div>

          <button
            className="bg-blue-500 text-white rounded-md px-4 py-2"
            type="submit"
          >
            Login
          </button>
        </div>
      </form>
    </main>
  );
}

方法2:升级Next.js版本(可选)

Next.js在13.4.13及后续版本中修复了组件内定义Server Action的问题。如果你想保留组件内定义的写法,可以升级到较新的稳定版:

npm install next@latest eslint-config-next@latest

升级后,原有的组件内定义Server Action的代码即可正常运行。

内容的提问来源于stack exchange,提问作者Marcellin123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 07:27:05