You know what useEffect does. You could explain the dependency array to a junior dev in your sleep. And yet — be honest — the last time you wrote one under any kind of pressure (a live coding round, a tight deadline, someone watching over your shoulder), did it come out clean on the first try?
If not, you're not bad at React. You've just never actually practiced it.
Knowing ≠ doing
This distinction sounds obvious once you say it out loud, but almost nobody applies it to how they learn React. We read the docs, we watch a tutorial, we nod along — and we quietly assume that comprehension is the same thing as skill.
It isn't. A musician doesn't get good at scales by reading about scales. An athlete doesn't get fast by watching game film alone. Skill comes from repetition under feedback — attempt, get corrected, attempt again. Most React learning skips the "attempt" part entirely and goes straight from "read" to "assume I've got it."
The specific gap: hooks
Hooks are where this gap shows up hardest, because they look simple. useState is one line. useEffect is a function and an array. It's easy to read a hook's signature, feel like you understand it, and never actually hit the edge cases that only show up when you're the one writing the code:
- Forgetting a cleanup function until you've got three intervals stacking on top of each other
- Mutating an array in state and wondering why nothing re-renders
- A stale closure inside an effect that's technically "working" but silently reading last render's value
None of these show up when you're reading someone else's correct code. They only show up when you write it yourself, get it subtly wrong, and have something tell you so.
A dumb-simple fix: the 3x3 drill
Here's a structure that actually works, borrowed straight from how deliberate practice works in any other skill:
- Pick three hooks for the week.
- For each one, do three challenges — one easy, one medium, one hard.
- Timebox each attempt. If you don't pass on the first try, don't peek at a solution immediately — rewrite it from scratch after you've sat with the failure for a bit.
A rough progression that works well:
Week 1 — useState, useReducer, useEffect
Week 2 — useRef, useMemo, useCallback
Week 3 — useContext, useLayoutEffect, useSyncExternalStore
Week 4 — Custom hooks: useDebounce, useInterval, usePrevious
Four weeks, 45 minutes a session, three sessions a week. That's it. That's the whole system.
What "correct" actually means here
The hard part isn't finding hook exercises — the internet is full of them. The hard part is knowing whether your solution is actually correct, not just "looks right to me." A written answer key can't catch a missing cleanup function or a mutated array — those bugs are silent until something breaks in a way you didn't predict.
What catches them is a real test suite mounting your component and interacting with it the way a user actually would — clicking fast, unmounting mid-effect, passing edge-case props. That's a fundamentally different (and much more honest) kind of feedback than eyeballing your own code.
I've been going through exactly this drill myself, hook by hook, using ReactGrind's hooks practice guide — it lays out the mental model and the common mistake for each hook, then links to an actual coding challenge with hidden tests for each one. It's the first resource I've found that treats "I understand this hook" and "I can write this hook correctly under pressure" as the two different things they actually are.
The takeaway
If you've been meaning to get sharper on hooks, skip another article that just explains what they do. You already know what they do. Go write ten of them badly this week, get told exactly where they broke, and rewrite them. That's the whole unlock.
If you want to jump straight in without reading a whole guide first, ReactGrind's full problem set is where the actual challenges live — hooks, state management, performance, the works, each one graded by a hidden test suite instead of an answer key.


Top comments (0)