- Home
- /
- Tutorials
- /
- React Tutorial
- /
- Where to Go Next
Custom Hooks and Patterns
Where to Go Next
You now know React. What remains is the ecosystem around it, and most of it is optional far longer than the job listings suggest.
What you have
Components, props, state, events, conditionals, lists, forms, effects, refs, context, reducers and custom hooks. That set builds real applications - everything below solves problems you will meet later, not gaps in the fundamentals.
Build something first
The most useful next step is not another topic. Build something with real data and a few screens, and let the gaps announce themselves - you will learn routing far better on the day you need a second page.
A small app touching most of it
jsx
function TodoApp() {
const [items, setItems] = React.useState([{ id: 1, text: "Learn React", done: true }])
const [draft, setDraft] = React.useState("")
const remaining = items.filter((i) => !i.done).length
function add(event) {
event.preventDefault()
if (!draft.trim()) return
setItems((current) => [...current, { id: Date.now(), text: draft.trim(), done: false }])
setDraft("")
}
const toggle = (id) =>
setItems((current) => current.map((i) => (i.id === id ? { ...i, done: !i.done } : i)))
return (
<div style={{ maxWidth: 320 }}>
<form onSubmit={add}>
<input value={draft} onChange={(e) => setDraft(e.target.value)} placeholder="Add an item" />{" "}
<button type="submit">Add</button>
</form>
<ul>
{items.map((item) => (
<li key={item.id}>
<label style={{ textDecoration: item.done ? "line-through" : "none" }}>
<input type="checkbox" checked={item.done} onChange={() => toggle(item.id)} />{" "}
{item.text}
</label>
</li>
))}
</ul>
<p>{remaining === 0 ? "All done" : `${remaining} remaining`}</p>
</div>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<TodoApp />)Controlled inputs, derived state, immutable updates, keys, form submission and conditional rendering - in about thirty lines. Nothing here is beyond what you have already covered.
In rough order of usefulness
- A build tool - Vite, so you are working in real files rather than a browser compiler.
- Routing - React Router, the moment you need a second page.
- Data fetching - TanStack Query. Caching and refetching are harder than they look, and this replaces a lot of
useEffect. - Forms - React Hook Form, once your validation outgrows a hand-written object.
- TypeScript - everything here still applies; you are adding types, not changing React.
- Testing - React Testing Library, which tests what the user sees rather than component internals.
- A framework - Next.js for routing, server rendering and data loading in one.
What you can safely ignore for now
- Redux -
useStateand context cover most applications. Add it when you have a problem they cannot solve. - Class components - worth recognising in old code, not worth learning to write.
- Server Components - a framework feature; learn them with the framework.
- Micro-optimisation - measure first, as the performance chapter argued.
The honest summary: the fundamentals in this tutorial are most of what you use daily. The libraries are tools for specific problems, and each is far easier to learn once you have actually had the problem it solves.
