- FrontendJoy
- Posts
- 17 React Hooks That Power 90% of Modern Components
17 React Hooks That Power 90% of Modern Components
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.
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.
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 😉.

💡 TIP OF THE WEEK
JavaScript Tip 💡
Use 𝙾𝚋𝚓𝚎𝚌𝚝.𝚎𝚗𝚝𝚛𝚒𝚎𝚜() + 𝙾𝚋𝚓𝚎𝚌𝚝.𝚏𝚛𝚘𝚖𝙴𝚗𝚝𝚛𝚒𝚎𝚜() to rename object keys.
— Ndeye Fatou Diop 🚢 💻 | DEV | 🇸🇳🇫🇷 (@_ndeyefatoudiop)
11:00 AM • May 8, 2025
Reply