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

Next.js 13:如何在客户端组件中使用异步服务端组件?

在客户端组件中使用异步服务端组件的解决方案

结论:不能直接在客户端组件(标记"use client")中渲染异步服务端组件。因为客户端组件运行在浏览器环境,无法处理服务端组件专属的服务端异步渲染逻辑,直接包裹Suspense会触发环境不兼容的错误。以下是可行的解决方法:


方案1:通过中间服务端组件中转

创建一个无"use client"标记的中间服务端组件,先在服务端完成异步服务端组件的渲染,再将结果作为props传递给客户端组件:

// 中间服务端组件(无"use client")
import { ChildSSC } from './ChildSSC';
import { ParentCSC } from './ParentCSC';

export async function MiddleSSC() {
  // 在服务端执行异步服务端组件的逻辑
  const childContent = await ChildSSC();
  return <ParentCSC childContent={childContent} />;
}

// 修改后的父级客户端组件
"use client"

export function ParentCSC({ childContent }: { childContent: React.ReactNode }) {
  return <div>{childContent}</div>;
}

方案2:将异步逻辑移至客户端

如果业务允许,把数据获取逻辑迁移到客户端,使用useEffect或数据获取库(如SWR、React Query)配合客户端Suspense(React 18+支持):

"use client"
import { Suspense, useState, useEffect } from 'react';

function FetchData() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch('/api/data');
      const result = await res.json();
      setData(result);
      setLoading(false);
    };
    fetchData();
  }, []);

  if (loading) return <div>加载中...</div>;
  return <div>{data}</div>;
}

export function ParentCSC() {
  return (
    <Suspense fallback={<div>加载中...</div>}>
      <FetchData />
    </Suspense>
  );
}

方案3:Next.js动态导入(禁用SSR)

若使用Next.js,可通过dynamic导入服务端组件并禁用SSR,将其转为客户端运行的组件(注意会失去服务端渲染优势):

"use client"
import dynamic from 'next/dynamic';

// 动态导入服务端组件,禁用SSR并设置加载态
const ChildSSC = dynamic(() => import('./ChildSSC'), { 
  ssr: false, 
  loading: () => <div>加载中...</div> 
});

export function ParentCSC() {
  return <ChildSSC />;
}

内容的提问来源于stack exchange,提问作者Keisuke Nagakawa 永川 圭介

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:10:27