typescriptbeginner

Server to Client Component Data Passing

Pass data from server components to client components using props and serialization patterns.

typescript
// Server Component fetches data
// app/dashboard/page.tsx (Server Component)
import { ClientChart } from './ClientChart';
import { InteractiveTable } from './InteractiveTable';

interface DashboardData {
  metrics: { label: string; value: number }[];
  chartData: { date: string; revenue: number }[];
  users: { id: string; name: string; role: string }[];
}

async function getDashboardData(): Promise<DashboardData> {
  const res = await fetch('https://api.example.com/dashboard', {
    next: { revalidate: 60 },
  });
  return res.json();
}

export default async function DashboardPage() {
  const data = await getDashboardData();

  return (
    <div>
      {/* Server-rendered static content */}
      <h1>Dashboard</h1>
      <div className="grid grid-cols-3 gap-4">
        {data.metrics.map((m) => (
          <div key={m.label} className="p-4 bg-gray-800 rounded-lg">
            <p className="text-gray-400">{m.label}</p>
            <p className="text-2xl font-bold">{m.value.toLocaleString()}</p>
          </div>
        ))}
      </div>

      {/* Client components receive serializable props */}
      <ClientChart data={data.chartData} />
      <InteractiveTable users={data.users} />
    </div>
  );
}

// ClientChart.tsx
'use client';

export function ClientChart({
  data,
}: {
  data: { date: string; revenue: number }[];
}) {
  // Can now use hooks, event handlers, browser APIs
  const [hoveredPoint, setHoveredPoint] = useState<number | null>(null);

  return (
    <div className="relative">
      {data.map((point, i) => (
        <div
          key={point.date}
          onMouseEnter={() => setHoveredPoint(i)}
          onMouseLeave={() => setHoveredPoint(null)}
          className="inline-block"
        >
          <div style={{ height: point.revenue / 100 }} className="w-8 bg-blue-500" />
          {hoveredPoint === i && <span>${point.revenue}</span>}
        </div>
      ))}
    </div>
  );
}

Use Cases

  • data hydration
  • interactive dashboards
  • server-client boundary

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.