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

Next.js 13中传递服务端函数给客户端组件报错,求排查

问题原因及修复方案

错误原因

你在服务端组件内定义了带"use server"的createTodo函数,然后直接把它作为props传给客户端组件,这种写法不符合Next.js Server Actions的规范——Server Actions要么作为顶层函数单独导出,要么在客户端组件内直接定义,不能在服务端组件内部定义后直接传递给客户端组件。

修复方案

方案一:将Server Action导出为顶层函数

把createTodo单独放在服务端组件的顶层(或者单独的文件中),再传递给客户端组件:

// 顶层导出Server Action
export async function createTodo(title: string) {
  "use server";
  // 确保user已通过服务端鉴权获取,比如Supabase Auth的服务端会话
  const { error } = await supabase.from("todos")
    .insert([{ id: user.id, title }]);
  return error;
}

// 服务端组件
const ServerComp: FC<{}> = () => {
  return <ClientComp createTodo={createTodo} />;
}

// 客户端组件(调整类型为异步函数)
"use client";
const ClientComp: FC<{ createTodo: (title:string) => Promise<any> }> = ({ createTodo }) => {
  return (
    <button onClick={() => createTodo("First Todo")}>ADD TODO</button>
  );
}

方案二:在客户端组件内直接定义Server Action

如果不需要在服务端组件中处理额外逻辑,可直接在客户端组件内定义Server Action:

// 客户端组件
"use client";
const ClientComp: FC = () => {
  const createTodo = async (title: string) => {
    "use server";
    // 这里的user需通过服务端鉴权获取,避免客户端传递敏感信息
    const { error } = await supabase.from("todos")
      .insert([{ id: user.id, title }]);
    return error;
  };

  return (
    <button onClick={() => createTodo("First Todo")}>ADD TODO</button>
  );
}

// 服务端组件
const ServerComp: FC<{}> = () => {
  return <ClientComp />;
}

注意事项

  • 客户端组件中createTodo的类型要调整为异步函数(返回Promise),因为Server Action本身是异步的
  • 确保user.id是通过服务端鉴权获取的,不要从客户端传递用户ID,避免安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:42:59