You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:42:07