使用shadcn/ui图表触发TypeError,如何在SSR下加载服务端数据?
解决shadcn/ui图表组件SSR报错及服务端数据加载问题
核心思路
问题本质是shadcn/ui依赖的图表底层库(如Recharts)属于客户端专属组件,无法在服务端渲染环境中运行;但数据可以提前在服务端完成获取,再传递给客户端组件进行渲染。
具体解决方案
1. 单独抽离图表为客户端组件
将MyChart组件单独拆分,在组件顶部添加"use client"指令,限定其仅在客户端执行:
// components/MyChart.tsx "use client"; import { LineChart, Line, XAxis, YAxis } from "@/components/ui/line-chart"; export default function MyChart({ data }: { data: Array<{ x: string; y: number }> }) { return ( <LineChart data={data}> <Line dataKey="y" /> <XAxis dataKey="x" /> <YAxis /> </LineChart> ); }
2. 服务端页面获取数据并传递给图表
保持Home页面为服务端组件,直接在页面内部完成数据获取(比如调用API、查询数据库),再将数据通过props传给客户端图表组件:
// app/page.tsx import MyChart from "@/components/MyChart"; async function fetchChartData() { // 服务端数据获取逻辑,示例为调用外部API const res = await fetch("https://api.example.com/chart-data", { cache: "force-cache" }); return res.json(); } export default async function Home() { const chartData = await fetchChartData(); return ( <div className="container mx-auto p-4"> <h1 className="text-2xl font-bold mb-4">服务端数据驱动图表</h1> <MyChart data={chartData} /> </div> ); }
3. 可选:添加数据加载状态
如果数据获取存在延迟,可在页面中加入加载占位符,优化用户体验:
// app/page.tsx import MyChart from "@/components/MyChart"; import { Skeleton } from "@/components/ui/skeleton"; async function fetchChartData() { const res = await fetch("https://api.example.com/chart-data", { cache: "force-cache" }); return res.json(); } export default async function Home() { const chartData = await fetchChartData(); return ( <div className="container mx-auto p-4"> <h1 className="text-2xl font-bold mb-4">服务端数据驱动图表</h1> {!chartData ? ( <Skeleton className="h-64 w-full" /> ) : ( <MyChart data={chartData} /> )} </div> ); }
方案原理
- 服务端页面负责数据获取,利用SSR特性提前完成数据拉取,避免客户端请求带来的延迟
- 图表组件作为客户端组件,仅负责渲染逻辑,避开了SSR环境无法运行客户端专属代码的限制
- 数据通过props从服务端传递到客户端,既保证了图表数据的时效性,又解决了组件渲染的环境冲突
内容的提问来源于stack exchange,提问作者jan
相关产品推荐
相关产品推荐

