Next.js 13 App Router中使用async组件报错:React子元素无效
Next.js 13 App Router 异步组件报错的解决办法
你碰到的这个错误,核心原因是async函数组件会返回Promise对象,但React渲染时需要的是React元素(JSX),直接把async组件当子元素渲染,本质是在渲染一个Promise,自然就触发了报错。
下面给你几种适配App Router模式的解决思路:
方案1:直接在服务器组件里写异步逻辑(推荐)
App Router下默认的组件都是服务器组件,支持直接用async/await,不用单独抽异步组件:
// page.tsx 或 Sidebar组件文件(无需加'use client') export default async function Sidebar() { const posts = await fetchPosts(); return <div>sidebar <div>async print posts...</div></div>; }
方案2:客户端组件用useEffect+useState处理异步
如果你的Sidebar必须是客户端组件(比如要用到交互hooks),就用状态管理异步请求:
'use client'; import { useState, useEffect } from 'react'; export default function Sidebar() { const [posts, setPosts] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const getPosts = async () => { const fetchedPosts = await fetchPosts(); setPosts(fetchedPosts); setLoading(false); }; getPosts(); }, []); if (loading) { return <div>sidebar loading...</div>; } return <div>sidebar <div>async print posts...</div></div>; }
方案3:用Suspense包裹异步服务器组件
要是一定要单独抽离异步逻辑,把异步部分做成服务器组件,再在客户端组件里用Suspense包裹:
// AsyncPosts.tsx(服务器组件,不要加'use client') export default async function AsyncPosts() { const posts = await fetchPosts(); return <div>async print posts...</div>; } // Sidebar.tsx(客户端组件) 'use client'; import { Suspense } from 'react'; import AsyncPosts from './AsyncPosts'; export default function Sidebar() { return ( <div> sidebar <Suspense fallback={<div>loading posts...</div>}> <AsyncPosts /> </Suspense> </div> ); }
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

