Stop 08 · ReactProjects · 4/6

Dashboard

Part of the Frontend Developer Roadmap

In short

Dashboards are what a lot of companies actually build in React. Cards, charts, filters and tables pulling from an API will make you very comfortable with data and effects.

A data-dense admin view combining stat cards, charts and tables — practice for composing many components together and managing shared/derived state.

The jaadu mascot looks at a phone showing a pie chart, a rising line graph and a coin card.

Think of it like this

Your banking app's home screen

One glance shows your balance, recent spends, a pie chart of where the money went and a filter for last month. Nothing fancy on its own, but it all reads from the same data and updates together. That's a dashboard.

Watch it happen

The slow June response

Month filter
useSales
API
Cards

month: June

1/7You pick June, and useSales runs its effect for June.

The big ideas

What you need to know

Grid layout

A sidebar, a top bar and a CSS grid of cards that reflows nicely on mobile.

Loading, error and data

Every widget has three states. Plan all three from day one, not just the happy path.

Charts from a library

Use a library like Recharts instead of drawing SVG by hand, and feed it derived data.

One filter, many widgets

A date range lives in the parent, and every card recalculates from it.

How it works

Build plan

  1. 1

    Shell

    Sidebar, header and an empty grid of cards.

  2. 2

    Fake data

    A JSON file of sales with dates, amounts and categories.

  3. 3

    Stat cards

    Totals and averages derived from the data.

  4. 4

    Chart and table

    A line chart over time and a sortable table.

  5. 5

    Filters

    A month or date range that every widget responds to.

See it in code

Walk through the code

ts
1import { useEffect, useState } from "react";2 3type Sale = { date: string; amount: number };4export function useSales(month: string) {5  const [sales, setSales] = useState<Sale[] | null>(null);6  const [error, setError] = useState<string | null>(null);7  useEffect(() => {8    let ignore = false;9    fetch("/api/sales?month=" + month)10      .then((r) => (r.ok ? r.json() : Promise.reject(new Error("HTTP " + r.status))))11      .then((data) => { if (!ignore) setSales(data); })12      .catch((e) => { if (!ignore) setError(e.message); });13    return () => { ignore = true; };14  }, [month]);15  return { sales, error, loading: sales === null && error === null };16}

1/4Two pieces of state: the sales data and any error.

If the user switches months quickly, the ignore flag drops the old response so it can't overwrite the newer one. In bigger apps, TanStack Query handles this for you.

Save yourself the pain

Common mistakes

Oops

Fetching in useEffect without any cleanup.

Do this instead

A slow old response can land after a new one and show the wrong month. Use an ignore flag or an AbortController.

Oops

Drawing every chart by hand in SVG.

Do this instead

Use a chart library and spend your time on the data and layout. That's what the job usually needs.

Your mission

First milestone: three stat cards

~40 min

Quick check

A user quickly switches from June to July, and June's slow response arrives last. Without cleanup, what shows?

Go deeper

  1. 1Break the dashboard into small, independent components (StatCard, ChartPanel, etc.).
  2. 2Use derived/computed values rather than duplicating state.
  3. 3Add loading skeletons for each panel independently.

More projects at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge