New to React?
If yes, you’ve probably wondered what hooks you really need—or worse, you’ve been copying the same logic over and over without realizing it.
This post covers all the React hooks you’ll likely need in your project.
Let’s dive in 🎉.
📚 Download my FREE 101 React Tips And Tricks Book for a head start.
1. useState
This hook is unavoidable.
Whenever you need dynamic state that persists across re-renders, this is the one.
const [count, setCount] = useState(0);
2. useReducer
Once your state becomes complex (e.g. multiple correlated fields), useReducer
becomes your friend.
It also pairs really well with useContext
, letting you update state with simple dispatch
calls.
const reducer = (state, action) => {
switch (action.type) {
case "addTodo":
return { todos: [...state.todos, action.todo] };
case "removeTodo":
// TODO: Implement logic
case "toggleTodo":
// TODO: Implement logic
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, { todos: [] });
3. useContext
When prop drilling gets out of hand, this hook saves the day.
Prop drilling = passing props through multiple layers just to reach a deeply nested component.
Use useContext
to:
manage global state in small apps
share data like the authenticated user
avoid passing props manually everywhere
const UserContext = createContext();
function App() {
const user = useUser();
return (
<UserContext.Provider value={user}>
{/* ... */}
</UserContext.Provider>
);
}
function Profile() {
const user = useContext(UserContext);
return <div>Hello {user.name}</div>;
}
4. useEffect
You should avoid it 99% of the time.
(See: You Might Not Need an Effect)
But in real life, you’ll still need it—especially for things like syncing with external systems.
function useSetDocumentTitle(title: string) {
useEffect(() => {
document.title = title;
}, [title]);
}
5. useRef
You should never directly manipulate the DOM in React.
But when you must (e.g. for canvas, chart libraries…), useRef
is the safe way.
function ExampleChart({ data }) {
const canvasRef = useRef();
useEffect(() => {
const ctx = canvasRef.current;
if (!ctx) return;
const chart = new Chart(ctx, {
type: "bar",
data: {
labels: data.map((row) => row.year),
datasets: [{ label: "Likes", data: data.map((r) => r.count) }],
},
});
return () => chart.destroy();
}, []);
return <canvas ref={canvasRef} />;
}
6. useMemo / useCallback
These may become optional thanks to the new React Compiler—but for now, they’re still useful.
Use useMemo
when:
an expensive computation should not re-run on every render
you're memoizing a non-primitive dependency
you're passing values to
memo
-wrapped components
Use useCallback
to memoize functions.
const total = useMemo(() => computeTotal(items), [items]);
const handleClick = useCallback(() => {
console.log("clicked");
}, []);
7. useLayoutEffect
This one is rare but useful.
It runs before paint, which helps prevent layout shifts or flickering UI.
See real examples here: No more flickering UI
If you’re not comfortable with React components lifecycle, check my post ✨ React Lifecycle in 3 Minutes 😉.
useLayoutEffect(() => {
const height = ref.current.offsetHeight;
setHeight(height);
}, []);
8. useSWR / useQuery
SWR and TanStack Query are becoming the standard for fetching data in React.
SWR is simpler and great for most use cases while TanStack Query is more complex and powerful.
SWR
const fetcher = (url) => fetch(url).then((res) => res.json());
const { data, error, isLoading } = useSWR("/api/user", fetcher);
TanStack Query
const getUser = () => fetch("/api/user").then((res) => res.json());
const { data, isLoading } = useQuery({
queryKey: ["user"],
queryFn: getUser,
});
9. useSelector, useDispatch, or other state hooks
Sometimes React’s built-in state tools aren’t enough.
You’ll then see these hooks depending on the state library:
useSelector
,useDispatch
from react-reduxuseAtom
from Jotaietc.
10. useNavigate
React Router is very popular.
So is its navigation hook:
const navigate = useNavigate();
navigate("/profile");
Now, let’s talk about hooks I reach for in nearly every app—even though they’re not built into React.
11. useBoolean
One of my all-time favorites.
It makes managing boolean state super clean.
const { value: isOpen, setFalse, toggle } = useBoolean();
return (
<>
<button onClick={toggle}>
{isOpen ? "Close form" : "Open form"}
</button>
<Dialog isOpen={isOpen} onClose={setFalse}>
{/* Form content */}
</Dialog>
</>
);
12. useCopyToClipboard
Perfect for "copy" buttons.
const [copiedText, copy] = useCopyToClipboard();
const handleCopy = () => {
copy("Hello World").catch(err => {
errorToast("Failed to copy!", err);
});
};
return (
<>
<button onClick={handleCopy}>Copy</button>
{copiedText && <span>Copied!</span>}
</>
);
13. usePrevious
Use this to compare current vs. previous values.
Great for triggering actions based on changes.
const prevCount = usePrevious(count);
const didIncrease = prevCount !== undefined && count > prevCount;
useEffect(() => {
if (didIncrease) {
console.log("Count increased!");
}
}, [didIncrease]);
14. useDebounce
Debounce your requests to avoid unnecessary API calls.
const [query, setQuery] = useState("");
const [debouncedQuery] = useDebounce(query, 500);
const { data } = useSWR(`/api/search?q=${debouncedQuery}`, fetcher);
return (
<>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
{/* TODO: Show data */}
</>
);
15. useMediaQuery
Want to render different things based on screen size? This hook is for you.
const isMobile = useMediaQuery("(max-width: 768px)");
return <div>{isMobile ? "Mobile View" : "Desktop View"}</div>;
16. useResizeObserver
Useful for responsive layouts or libraries like react-window.
const ref = useRef(null);
const { width = 0, height = 0 } = useResizeObserver({ ref });
return (
<div ref={ref}>
Width: {width}, Height: {height}
</div>
);
17. useLocalStorage
Store and sync data with localStorage
easily.
const [theme, setTheme] = useLocalStorage("theme", "light");
return (
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Switch to {theme === "light" ? "dark" : "light"}
</button>
);
Summary
That’s it!
These 17 hooks are more than enough to cover most use cases in any React app.
Pick your favorites and use them in your next project 😉.
If you're learning React, download my 101 React Tips & Tricks book for FREE.
If you like articles like this, join my FREE newsletter, FrontendJoy.
Top comments (11)
Let’s agree, we have used useSWR so many times on the client side. The name just sounds cool for some reason.
Ahah indeed! Such a quick way to get started!
pretty cool list, makes me wish i had this when i started out - you think getting better with react is more about just banging out projects or actually digging into stuff like this every day?
Hello Nevo, super glad you like it!
I think it is a mix. Definitely build projects, but try to explore what is out there. That gives you more tools to use :)
Awesome breakdown! As someone learning hooks, this is super helpful. I’ve been using useEffect everywhere—time to explore all these as well.
Super glad you like them! Oh definitely try to reduce the number of times you use effect ;)
This list is ridiculously useful, especially the bonus utility hooks! Curious - which one do you personally use the most in your day-to-day projects?
Super glad you like them! Thanks! If I had to give a top 5, it would be:
Looks like a great one for the beginners 😁
Thanks!
Which of these hooks do you find yourself using the most in your own React projects?