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

React Hook Form+Next.js14 Server Actions文件上传报错求助

Next.js 14 + React Hook Form 文件上传Server Actions报错解决办法

问题重现

使用React Hook Form注册文件输入框后,选择文件提交时触发如下错误:

Uncaught Error: Only plain objects, and a few built-ins, can be passed to Server Actions. Classes or null prototypes are not supported.

不选择文件时流程正常,但尝试构造新FormData传递文件时,Server Action仅收到空FileList数组,无法完成上传。

解决步骤

1. 客户端手动构建原生FormData

不要直接把React Hook Form处理后的表单数据传给Server Action,而是手动创建原生FormData,提取文件后再传递:

"use client"
import { useForm } from "react-hook-form";

export default function ProfileForm() {
  const { register, handleSubmit, getValues } = useForm();

  const onSubmit = async () => {
    const formData = new FormData();
    // RHF中文件输入返回的是File数组,取第一个元素
    const avatarFile = getValues("avatar_url")?.[0];
    if (avatarFile) {
      formData.append("avatar_url", avatarFile);
    }
    // 调用Server Action
    await updateUserProfile(formData);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register("avatar_url")}
        type="file"
        name="avatar_url"
        accept="image/*"
      />
      <button type="submit">upload</button>
    </form>
  );
}

2. Server Action接收原生FormData处理上传

在Server Action中直接从FormData获取文件,调用Supabase Storage API完成上传:

"use server"
import { supabase } from "@/lib/supabase";

export async function updateUserProfile(formData) {
  const file = formData.get("avatar_url");
  if (!file) return;

  // 替换为你的Supabase存储桶名称和自定义文件路径规则
  const { data, error } = await supabase.storage
    .from("avatars")
    .upload(`user-assets/${file.name}`, file, {
      cacheControl: "3600",
      upsert: true // 若文件已存在则覆盖
    });

  if (error) {
    throw error;
  }

  // 可选:获取文件公开链接并更新用户资料
  const { data: publicUrlData } = supabase.storage
    .from("avatars")
    .getPublicUrl(data.path);

  // 此处可添加更新用户表的逻辑
  // await supabase.from("users").update({ avatar_url: publicUrlData.publicUrl }).eq("id", 当前用户ID);

  return publicUrlData;
}

原因说明

React Hook Form的handleSubmit默认会把表单数据转换成包含FileList的对象,而Server Action不支持传递FileList这类非普通对象。手动构建原生FormData并传递,就能避开这个限制,让文件正确到达Server Action。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:03:39