If you've recently started your journey into the world of React, you've probably come across the term "custom hooks." These powerful abstractions allow you to extract reusable logic from components and make your code cleaner, more readable, and easier to maintain.
In this post, we’ll explore 7 beginner-friendly custom hooks that can significantly enhance your React development experience. Let’s dive in!
1️⃣ useMediaQuery
– Reactively Handle Screen Sizes
Modern applications must be responsive. useMediaQuery
helps you reactively check if a specific CSS media query matches the current screen size.
import { useState, useEffect } from "react";
const useMediaQuery = (query) => {
const [matches, setMatches] = useState(false);
useEffect(() => {
const media = window.matchMedia(query);
setMatches(media.matches);
const listener = () => setMatches(media.matches);
media.addEventListener("change", listener);
return () => media.removeEventListener("change", listener);
}, [query]);
return matches;
};
// Usage
const isMobile = useMediaQuery("(max-width: 768px)");
✅ Great for conditional rendering based on screen width.
2️⃣ useBreakpoint
– Responsive Design Made Easy
Building on useMediaQuery
, you can create a more organized hook to detect specific breakpoints (like xs
, sm
, md
, lg
, etc.).
const useBreakpoint = () => {
const isXs = useMediaQuery('(max-width: 576px)');
const isSm = useMediaQuery('(min-width: 577px) and (max-width: 768px)');
const isMd = useMediaQuery('(min-width: 769px) and (max-width: 992px)');
const isLg = useMediaQuery('(min-width: 993px) and (max-width: 1200px)');
const isXl = useMediaQuery('(min-width: 1201px)');
return { isXs, isSm, isMd, isLg, isXl };
};
✅ Helps you apply screen-specific logic easily.
3️⃣ useDebounce
– Delay Rapid Function Calls
Debouncing prevents a function from being called too frequently—very useful for search inputs, API calls, and filters.
import { useState, useEffect } from "react";
const useDebounce = (value, delay = 300) => {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debounced;
};
// Usage
const debouncedSearchTerm = useDebounce(searchTerm, 500);
✅ Improve performance and reduce unnecessary calls.
4️⃣ useThrottle
– Limit Function Execution Rate
Similar to debounce, but throttle ensures the function is only executed once every fixed interval, no matter how many times it's triggered.
import { useRef, useState, useEffect } from "react";
const useThrottle = (value, limit = 300) => {
const [throttledValue, setThrottledValue] = useState(value);
const lastRan = useRef(Date.now());
useEffect(() => {
const handler = setTimeout(() => {
if (Date.now() - lastRan.current >= limit) {
setThrottledValue(value);
lastRan.current = Date.now();
}
}, limit - (Date.now() - lastRan.current));
return () => clearTimeout(handler);
}, [value, limit]);
return throttledValue;
};
✅ Great for scroll events or resize listeners.
5️⃣ useLocalStorage
– Persist Data Across Sessions
Want to remember user preferences? useLocalStorage
provides a simple way to get and set values in the browser’s localStorage.
const useLocalStorage = (key, initialValue) => {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch {
return initialValue;
}
});
const setValue = (value) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue];
};
✅ Perfect for themes, login tokens, or settings.
6️⃣ useClickOutside
– Detect Outside Clicks
Very helpful for modals, dropdowns, and popups. It triggers an action when a user clicks outside of a given ref.
const useClickOutside = (ref, callback) => {
useEffect(() => {
const handleClick = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
callback();
}
};
document.addEventListener("mousedown", handleClick);
return () => document.removeEventListener("mousedown", handleClick);
}, [ref, callback]);
};
✅ Keeps your UI interactions intuitive.
7️⃣ usePrevious
– Get Previous State Value
Ever needed to compare current and previous values? This hook stores and returns the previous state or prop.
import { useEffect, useRef } from "react";
const usePrevious = (value) => {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
};
✅ Useful for tracking value changes or animations.
📌 Final Thoughts
Custom hooks are like secret tools in your React toolbox. As a beginner, learning to build and use them not only makes you more productive but also deepens your understanding of React’s powerful hook system.
👉 Start by copying and customizing the examples above. Over time, you’ll build your own set of reusable hooks tailored to your projects.
Top comments (0)