Next.js 13页面设为async函数出现React子元素错误如何解决?
修复Next.js 13 Async页面的"Objects are not valid as a React child"错误
问题根源
- fetch调用格式错误:你把配置对象直接传给
fetch,但fetch的第一个参数必须是URL字符串,配置对象是第二个参数。 - Async组件中误用React Hooks:Next.js 13 App Router里,async页面默认是服务器组件,服务器组件不支持
useEffect这类客户端Hooks;同时async组件本身会返回Promise,这违背了React对组件返回值的要求(需返回React元素或null)。
修复步骤
1. 修正getData函数的fetch调用
const getData = async () => { const res = await fetch("http://localhost:3000/api/user/getOne", { method: "POST", credentials: "include", // 注意参数为字符串"include",而非布尔值true headers: { "Content-Type": "application/json", // POST请求必须设置该请求头 }, body: JSON.stringify({ userId: "637846eb8f36e20663a9c948", }), }); if (!res.ok) { throw new Error("获取数据失败"); } return res.json(); // 将Response解析为JSON格式数据 };
2. 调整Async页面组件,移除Hooks
服务器组件中直接通过await获取数据即可,无需使用useEffect:
export default async function Page() { // 服务器组件中直接await获取数据 const profileData = await getData(); // 直接打印数据,不需要依赖useEffect console.log(profileData); return ( <div> <p>Hello</p> {/* 若要渲染数据,确保数据是可直接渲染的类型(如字符串、数字) */} <p>用户ID:{profileData.userId}</p> </div> ); }
3. 若需客户端副作用,拆分客户端组件
如果必须使用useEffect这类客户端逻辑,将这部分拆分为单独的客户端组件,添加'use client'指令:
// components/ProfileClient.js 'use client'; import { useEffect } from 'react'; export default function ProfileClient({ profileData }) { useEffect(() => { console.log("客户端打印:", profileData); // 在这里编写客户端副作用逻辑,比如DOM操作、事件监听等 }, [profileData]); return <p>客户端渲染数据:{profileData.name}</p>; }
然后在async页面中引入该客户端组件:
// app/page.js import ProfileClient from '@/components/ProfileClient'; export default async function Page() { const profileData = await getData(); return ( <div> <p>Hello</p> <ProfileClient profileData={profileData} /> </div> ); }
关键注意事项
- Next.js 13 App Router中,async页面默认是服务器组件,不能使用任何React Hooks,也无法访问浏览器API。
- fetch的
credentials参数有效值为"include"、"same-origin"或"omit",不是布尔类型。 - POST请求必须将body转为JSON字符串,并设置
Content-Type: application/json请求头。
内容的提问来源于stack exchange,提问作者crayonne
相关产品推荐
相关产品推荐

