Skip to content
UT Studio

React dashboard design patterns that hold up

Composition, URL state and server boundaries — the patterns that stay pleasant past ten screens.

UT Studio7 min read

Dashboard code decays in predictable ways. Three patterns prevent most of it, and none of them require a library.

Compose, do not configure

The instinct with a repeated component is to add props. Twelve screens later the table takes thirty of them and every change risks all twelve.

Two shapes
// Configuration: every new need is another prop.
<DataTable rows={rows} showFilters showExport onExport={…} dense stickyHeader />

// Composition: every new need is another child.
<Table>
  <Table.Toolbar><Filters /><ExportButton /></Table.Toolbar>
  <Table.Body rows={rows} />
  <Table.Pagination />
</Table>

Put view state in the URL

Filters, sort, page and the selected tab belong in the query string — not in component state, and not in a store.

  • The view is shareable, which is most of what internal tools are used for.
  • Back works, and refresh does not reset the screen.
  • It can be read on the server, so the first paint is already correct.
  • You delete a state management dependency.

Keep client boundaries at the leaves

A table is not interactive. Its sort control is. Marking the whole table as a client component to make one header clickable ships every row to the browser as JavaScript.

Pass data down, not imports across

A client island should take what it needs as props. Importing the data module from inside a client component drags the module — and everything it imports — into the bundle.

One loading strategy per screen

Mixing route-level loading, per-component spinners and skeletons on one screen produces a page that flashes three times. Pick one per screen and hold it.

Patterns worth avoiding

PatternProblem
Global store for server dataTwo sources of truth, and cache invalidation you now own
Prop-drilling through five levelsA composition problem wearing a state costume
useEffect for data fetchingWaterfalls, and a loading state that could have been server-rendered
Context for anything that changes oftenRe-renders every consumer

Templates built this way

Templates mentioned here

Everything above is written against real products. These are the ones this page draws on.

Read next