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
相关产品推荐
相关产品推荐

