Stop 08 · ReactTopics · 20/20

React Patterns

Part of the Frontend Developer Roadmap

In short

Once you know the hooks, the next level is knowing how to arrange components. A handful of patterns show up in almost every well-built React codebase.

Established solutions to common React problems — compound components, controlled/uncontrolled, container/presentational — that make codebases more consistent and maintainable.

The jaadu mascot as a cricket captain waves fielders into their positions.

Think of it like this

Field placements in cricket

Captains don't invent a field from scratch every over. There's a known setup for a spinner, one for the death overs, one for a new batter. React patterns are the same: tried and tested setups for problems that keep coming up.

Watch it happen

Lifting state up

Converter
TempInput
°F text

value: 25

1/6Converter owns celsius and passes 25 down to TempInput as a prop.

The big ideas

What you need to know

Lift state up

When two siblings need the same data, move the state to their closest common parent and pass it down.

Container and presentational

One component fetches data and handles logic, another just shows it. Both become easier to test and reuse.

Compound components

Parts that work together, like Tabs, TabList and TabPanel, sharing state through context.

Composition with children

Pass components as children instead of adding endless props. A Card doesn't need a showFooterButton prop.

See it in code

Walk through the code

tsx
1import { useState } from "react";2 3function TempInput({ value, onChange }: { value: number; onChange: (v: number) => void }) {4  return <input type="number" value={value} onChange={(e) => onChange(Number(e.target.value))} />;5}6 7export default function Converter() {8  const [celsius, setCelsius] = useState(25); // lifted to the parent9  return (10    <>11      <TempInput value={celsius} onChange={setCelsius} />12      <p>{((celsius * 9) / 5 + 32).toFixed(1)} °F</p>13    </>14  );15}

1/4TempInput has no state. It shows value and reports changes through onChange.

TempInput owns no state. The parent does, so the input and the °F text always agree. That's lifting state up in its smallest form.

Save yourself the pain

Common mistakes

Oops

Keeping a copy of the same data in two sibling components.

Do this instead

Two copies drift apart. Keep one source of truth in the common parent.

Oops

Adding a new boolean prop for every layout tweak.

Do this instead

If a component has props like showIcon, showFooter and footerText, switch to children or compound components.

Your mission

Build compound Tabs

~40 min

Quick check

Two sibling components both need to know which city is selected. Where should that state live?

Go deeper

  1. 1Study the 'compound components' pattern (e.g. how `<Select><Option/></Select>` works).
  2. 2Refactor one component into 'container' (logic) and 'presentational' (UI) halves.
  3. 3Read how a popular open-source component library structures its components.

More topics 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