Hooks
- React
Special functions that let function components use React features like state and side effects, subject to the Rules of Hooks that keep them reliable.
Prerequisites
- State and how it triggers re-renders (see Related Topics)
What you'll understand
- What hooks are and what they unlock in function components
- The two most common hooks and what they do
- The Rules of Hooks and why they exist
Explanation
Hooks are special functions that let a function component tap into React features that would otherwise be out of reach, such as remembering state or running side effects. Their names start with use, and they are the mechanism that makes small function components as capable as the class components React used to rely on.
Two hooks cover most everyday needs. useState gives a component its own state (see Related Topics). useEffect runs side effects, work that reaches outside React, like fetching data, setting up a subscription, or syncing with the browser, after the component renders, and can clean up after itself. Beyond these, React provides more hooks, and you can extract logic into your own custom hooks, a topic in its own right.
Hooks come with two Rules of Hooks that must be followed. Call hooks only at the top level of a component, never inside a condition, loop, or nested function, so the order of hook calls is identical on every render. And call them only from React function components or from other hooks. React relies on a consistent call order to track each hook, so breaking these rules leads to unpredictable behaviour; a linter rule enforces them for you.
Examples
useEffect runs a side effect after render, and its dependency array controls when it re-runs:
import { useEffect, useState } from 'react';
function Profile({ userId }: { userId: number }) {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]); // re-runs only when userId changes
return <p>{user?.name ?? 'Loading...'}</p>;
}Hooks must be called at the top level, never conditionally, so their order is stable:
const [count, setCount] = useState(0); // correct: top level
// if (ready) { const [x] = useState(0); } // wrong: conditional hookCommon mistakes
- Calling a hook inside a condition, loop, or nested function.
- Calling hooks outside a component or custom hook.
- Omitting or misfilling the useEffect dependency array, causing stale data or extra runs.
- Using an effect for work that could be done during render or in an event handler.
Best practices
- Call hooks only at the top level of components or custom hooks.
- Use useState for state and useEffect for genuine side effects.
- List every value an effect depends on in its dependency array.
- Keep the lint rule for hooks enabled to catch violations early.
Further reading
- React, Built-in React Hooks — https://react.dev/reference/react/hooks
- React, Rules of Hooks — https://react.dev/reference/rules/rules-of-hooks