Next.js14 React Query报错:仅允许普通对象从服务端组件传至客户端组件
排查与解决步骤
1. 确认组件的客户端标识
- 检查
PublishedMovieList组件顶部是否添加了'use client'指令。如果它依赖React Query这类客户端库,必须标记为Client Component;同时要注意,Server Component向Client Component传递的props必须是可序列化的普通对象。
2. 检查Server Component(page.tsx)传递的props
如果page.tsx是默认的Server Component,它传给PublishedMovieList的任何数据都必须是纯普通对象:
- 若你在page中通过接口获取数据,确保只传递响应里的纯数据部分,而非整个响应对象或类实例。比如用axios时,要解构出
data属性再传递:// 错误:传递了AxiosResponse类实例 const response = await axios.get('/api/movies'); return <PublishedMovieList movies={response} />; // 正确:只传递纯数据 const { data } = await axios.get('/api/movies'); return <PublishedMovieList movies={data} />; - 若你在page中用类封装了数据(比如
new Movie(item)),要把类实例转为普通对象:// 错误:传递类实例 const movies = rawMovies.map(item => new Movie(item)); return <PublishedMovieList movies={movies} />; // 正确:转为普通对象 const movies = rawMovies.map(item => ({ ...item })); return <PublishedMovieList movies={movies} />;
3. 检查PublishedMovieList内部数据处理
即使注释了useFetchData,组件内部可能存在生成非普通对象的逻辑:
- 避免使用
Object.create(null)创建对象(这类对象无原型,不符合Next.js的props要求),改用字面量{}创建。 - 检查是否有将props数据转换为类实例的代码,比如:
// 错误:在Client Component中生成类实例并传递给子组件 const movieInstances = movies.map(m => new Movie(m)); return <MovieItem movie={movieInstances} />; // 正确:直接传递普通对象 return <MovieItem movie={m} />;
4. 验证数据结构
在传递props前,打印数据的原型信息确认是否为普通对象:
// 在page.tsx中打印验证 console.log(Object.getPrototypeOf(movies[0]) === Object.prototype); // 应为true
如果返回false,说明该对象不是普通对象,需要转换。
内容的提问来源于stack exchange,提问作者Nats
相关产品推荐
相关产品推荐

