React hooks explained in plain terms: hooks are just functions that let your components remember things and respond to change without writing a class. If you learned React before 2019 you wrote classes; today you write functions and call hooks like useState and useEffect. This guide is for beginners in 2026, and it is honest about which hooks you actually need and which ones you can happily ignore for months.
What changed in 2026
React 19 is now the mainstream version, and it reshaped day-to-day hook usage:
- The React Compiler auto-memoizes components, so a lot of hand-written useMemo and useCallback is no longer necessary. Check whether your project has it enabled before ripping anything out.
- The new use hook can read a promise or context, and unlike every other hook it may be called conditionally.
- Form and action hooks — useActionState, useFormStatus, and useOptimistic — make submissions and pending states far less painful.
- Refs as props — you rarely need forwardRef anymore; a ref can be passed like a normal prop.
Treat version-specific claims as directional and check the current React docs yourself, since minor releases move fast.
The rules of hooks, and why they exist
Two rules cover almost everything:
- Only call hooks at the top level of a component or another hook — never inside loops, conditions, or nested functions (the new use hook is the one exception).
- Only call hooks from React function components or custom hooks, not plain JavaScript functions.
Why? React tracks hooks by call order. If you hide a useState behind an if statement, the order shifts between renders and state gets crossed. Install eslint-plugin-react-hooks and let it catch these for you; it is the single highest-value setup step.
useState: the hook you will use most
useState gives a component a piece of memory. It returns the current value and a setter.
const [count, setCount] = useState(0);
// later
setCount(c => c + 1); // updater form when the next value depends on the last
Two beginner traps: state updates are batched and asynchronous, so reading count right after setCount shows the old value; and never mutate state directly — always pass a new object or array.
useEffect: powerful, and overused
useEffect runs code after render, for things outside React like subscriptions, timers, or manual DOM work.
useEffect(() => {
const id = setInterval(tick, 1000);
return () => clearInterval(id); // cleanup on unmount or dep change
}, []);
The honest caveat: most beginners overuse it. If you can calculate a value from existing props or state during render, do that instead of syncing it with an effect. Data fetching is increasingly handled by frameworks or libraries (React Query, Next.js) rather than a raw useEffect.
The 2026 hook cheat sheet
| Hook |
Use it for |
Beginner priority |
| useState |
Local component state |
Learn first |
| useEffect |
Side effects, subscriptions |
Learn second, use sparingly |
| useContext |
Reading shared or global values |
Soon after |
| useRef |
DOM refs, values that persist without re-render |
As needed |
| useReducer |
Complex state with many transitions |
Later |
| useMemo / useCallback |
Manual memoization |
Often unneeded with the Compiler |
| use (React 19) |
Reading promises or context |
When you meet it |
Common mistakes and what to skip
- Missing dependencies in useEffect. The lint rule flags them; do not silence it blindly.
- Reaching for useEffect to derive data you could compute in render.
- Premature useMemo/useCallback. With the React Compiler, hand-memoizing early is wasted effort — measure first.
- Skip: installing a state-management library on day one. useState plus useContext handles most small apps; add Redux or Zustand only when prop-drilling genuinely hurts.
FAQ
Do I need to learn class components in 2026?
No, not to start. Hooks are the default and new code is function-based. Learn classes only if you maintain an older codebase.
Why does my useEffect run twice in development?
React Strict Mode intentionally double-invokes effects in development to surface missing cleanup. It does not happen in production builds.
Can I write my own hook?
Yes. A custom hook is just a function whose name starts with use and calls other hooks. It is the standard way to share stateful logic between components.
Is the React Compiler mandatory?
No. It is opt-in per project. Without it, you still manage memoization by hand with useMemo and useCallback.
Where to go next
Once hooks click, deepen the fundamentals with Async/await explained in 2026, pick your tooling with Best AI coding assistants in 2026, and compare frameworks in Astro vs Next.js in 2026.