Next.js 13 app目录迁移报错:Objects are not valid as a React child
问题原因与解决方案
错误根源
你遇到的错误是因为标记了"use client"的客户端组件无法直接渲染异步组件(async function Component)。在Next.js 13的app目录中,async组件默认属于Server Component,它的返回值是Promise,而客户端React环境无法将Promise作为React子元素渲染,因此抛出该错误。
解决方案
方案一:调整组件结构,用Server Component作为容器
如果Post组件不需要是客户端组件(即不依赖交互状态、浏览器API等),可以移除Post顶部的"use client",让它成为Server Component,这样就能直接渲染异步的Comments组件:
// Post.js(移除"use client",变为Server Component) import Comments from "./Comments"; const Post = () => { return ( <div> <p>This is a post</p> <Comments /> </div> ); }; export default Post;
// Comments.js(保持async,作为Server Component) export default async function Comments() { const res = await fetch("https://jsonplaceholder.typicode.com/comments"); const comments = await res.json(); return <div>{comments.map(comment => <p key={comment.id}>{comment.body}</p>)}</div>; }
方案二:将Comments改为客户端组件,内部处理异步逻辑
如果Post必须是客户端组件,那么需要把Comments也改为客户端组件,用React状态钩子处理异步请求:
// Post.js(保留"use client") import Comments from "./Comments"; const Post = () => { return ( <div> <p>This is a post</p> <Comments /> </div> ); }; export default Post;
// Comments.js(添加"use client",用useEffect+useState处理异步) "use client"; import { useState, useEffect } from "react"; export default function Comments() { const [comments, setComments] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const fetchComments = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/comments"); const data = await res.json(); setComments(data); setLoading(false); }; fetchComments(); }, []); if (loading) return <div>Loading comments...</div>; return <div>{comments.map(comment => <p key={comment.id}>{comment.body}</p>)}</div>; }
内容的提问来源于stack exchange,提问作者Akshey Sharma
相关产品推荐
相关产品推荐

