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

Next.js13使用Server Action提交表单报错:backingFormData.forEach is not a function

解决Next.js 13中Server Action报错Error: backingFormData.forEach is not a function的问题

可能原因及解决方案

1. 确认Next.js版本并升级

Server Action在Next.js 13.4及以上版本才进入稳定支持阶段,若你的版本低于13.4,需先升级:

npm install next@latest react@latest react-dom@latest

2. 正确配置next.config.js

确保配置文件中启用Server Action(13.4+版本App Router默认支持,但部分场景仍需显式配置):

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverActions: true,
  },
};

module.exports = nextConfig;

配置完成后重启开发服务器。

3. 调整Server Action的写法

方案一:将Server Action移至组件外部

避免在异步页面组件内部定义Server Action,将其提取到组件外部:

import { useState} from 'react'

export interface Product {
  id?: number;
  product: string;
  price: string;
}

// Server Action移至组件外部,"use server"单独占一行
async function addProductToDatabase(e: FormData) {
  "use server";
  const product = e.get("product")?.toString();
  const price = e.get("price")?.toString();
  if (!product || !price) return;
  const newProduct: Product = {
    product,
    price
  };
  await fetch('https://64bda1242320b36433c7c958.mockapi.io/product', {
    method: 'POST',
    body: JSON.stringify(newProduct),
    headers: {
      'Content-Type':'application/json'
    }
  });
}

export default async function Home() {
  const res = await fetch(
    "https://64bda1242320b36433c7c958.mockapi.io/product",
    {
      cache: "no-cache",
    }
  );
  const products: Product[] = await res.json();

  return (
    <main>
      <h1 className="text-3xl font-bold text-center">
        Testing product server function
      </h1>

      <form
        action={addProductToDatabase}
        className="flex flex-col gap-5 max-w-xl mx-auto p-5"
      >
        <input
          name="product"
          type="text"
          className="border border-gray-300 p-2 rounded-md"
          placeholder="Enter product name"
        />
        <input
          name="price"
          type="text"
          className="border border-gray-300 p-2 rounded-md"
          placeholder="Enter product price"
        />
        <button className="border bg-blue-500 text-white p-2 rounded-md">
          Add product
        </button>
      </form>

      <h2 className="font-bold p-5">list of products</h2>
      <div className="flex flex-wrap gap-5">
        {products.map((product) => (
          <div key={product.id} className="p-5 shadow">
            <p>{product.product}</p>
            <p>R$: {product.price}</p>
          </div>
        ))}
      </div>
    </main>
  );
}

方案二:将Server Action单独拆分到文件中

推荐将Server Action集中管理,创建app/actions.ts文件:

"use server";

export interface Product {
  id?: number;
  product: string;
  price: string;
}

export async function addProductToDatabase(formData: FormData) {
  const product = formData.get("product")?.toString();
  const price = formData.get("price")?.toString();
  if (!product || !price) return;
  const newProduct: Product = { product, price };
  await fetch('https://64bda1242320b36433c7c958.mockapi.io/product', {
    method: 'POST',
    body: JSON.stringify(newProduct),
    headers: { 'Content-Type':'application/json' }
  });
}

然后在页面组件中导入使用:

import { addProductToDatabase, Product } from './actions';

export default async function Home() {
  const res = await fetch(
    "https://64bda1242320b36433c7c958.mockapi.io/product",
    { cache: "no-cache" }
  );
  const products: Product[] = await res.json();

  return (
    <main>
      <h1 className="text-3xl font-bold text-center">
        Testing product server function
      </h1>

      <form
        action={addProductToDatabase}
        className="flex flex-col gap-5 max-w-xl mx-auto p-5"
      >
        <input
          name="product"
          type="text"
          className="border border-gray-300 p-2 rounded-md"
          placeholder="Enter product name"
        />
        <input
          name="price"
          type="text"
          className="border border-gray-300 p-2 rounded-md"
          placeholder="Enter product price"
        />
        <button className="border bg-blue-500 text-white p-2 rounded-md">
          Add product
        </button>
      </form>

      <h2 className="font-bold p-5">list of products</h2>
      <div className="flex flex-wrap gap-5">
        {products.map((product) => (
          <div key={product.id} className="p-5 shadow">
            <p>{product.product}</p>
            <p>R$: {product.price}</p>
          </div>
        ))}
      </div>
    </main>
  );
}

4. 检查页面组件的渲染模式

若你使用的是Page Router(pages目录下的组件),Server Action的启用方式略有不同:

  • 同样需要在next.config.js中启用serverActions
  • Server Action需定义在pages目录下的文件中,或单独的action文件,并确保"use server"指令正确

关键注意点

  • "use server"指令必须单独占据一行,不能与其他代码同行
  • Server Action的参数必须是FormData类型,无需手动解析表单数据,Next.js会自动传递
  • 确保开发服务器在修改配置后重启,否则配置不会生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:17:02