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

Next.js 13使用Tremor图表时Value Formatter传参报错求助

解决Next.js 13 + Tremor组件库中Value Formatter函数传递报错问题

在Next.js 13项目中使用Tremor的LineChart组件时,启用valueFormatter={numberFormatter}会触发以下错误:

Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server"

问题原因

Next.js 13 App Router中,组件默认是Server Component,而Tremor的图表组件属于Client Component(依赖浏览器环境渲染)。Server Component无法直接将函数传递给Client Component,这是报错的核心原因。


解决方案

方法一:在服务器端提前格式化数据

直接在数据转换阶段完成数值格式化,避免向Client Component传递函数:

修改transformedData的处理逻辑:

const transformedData = items.map((item) => {
  const date = new Date(item.createdAt);
  return {
    createdAt: formatDate.format(date),
    // 提前在服务器端格式化数值
    value: numberFormatter(item.value)
  };
});

随后在Linechart组件中移除valueFormatter属性:

<Linechart
  data={transformedData}
  categories={["value"]}
  index={"createdAt"}
  color={"teal"}
  curveType={"monotone"}
  maxValue={2500000}
/>

方法二:拆分组件,将格式化函数放在Client Component中

  1. 创建带'use client'标记的Client组件(例如ClientLineChart.tsx),在内部定义格式化函数:
'use client';

import { LineChart } from "@tremor/react";

const numberFormatter = (value: number) =>
  `${Intl.NumberFormat("us").format(value).toString()}`;

export default function ClientLineChart(props: {
  data: any[];
  categories: string[];
  index: string;
  color: string;
  curveType: string;
  maxValue: number;
}) {
  return (
    <LineChart
      data={props.data}
      categories={props.categories}
      index={props.index}
      valueFormatter={numberFormatter}
      color={props.color}
      curveType={props.curveType}
      maxValue={props.maxValue}
    />
  );
}
  1. 在原DashboardNetworth组件(Server Component,无需'use client')中导入并使用该Client组件:
import { getAuthSession } from "@/lib/auth";
import { db } from "@/lib/db";
import { Card, Text, Title } from "@tremor/react";
import ClientLineChart from "./ClientLineChart";

const formatDate = new Intl.DateTimeFormat("en-US", {
  month: "short",
  year: "numeric",
  day: "numeric",
});

const DashboardNetworth = async () => {
  const session = await getAuthSession();

  const items = await db.item.findMany({
    where: {
      creatorId: session?.user.id,
    },
  });

  const transformedData = items.map((item) => {
    const date = new Date(item.createdAt);
    return {
      createdAt: formatDate.format(date),
      value: item.value // 保留数值类型,由Client组件负责格式化
    };
  });

  return (
    <Card className="h-[400px]">
      <div className="block sm:flex sm:justify-between">
        <div>
          <Title>Networth</Title>
          <Text>Total networth over time</Text>
        </div>
      </div>
      
      <ClientLineChart
        data={transformedData}
        categories={["value"]}
        index={"createdAt"}
        color={"teal"}
        curveType={"monotone"}
        maxValue={2500000}
      />
    </Card>
  );
};

export default DashboardNetworth;

内容的提问来源于stack exchange,提问作者Jordy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:28:21