DEV Community

Muhammed Fayaz T S
Muhammed Fayaz T S

Posted on

2 1 1 1

7 Useful Custom Hooks Every React Beginner Should Know

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)");
Enter fullscreen mode Exit fullscreen mode

✅ 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 };
};
Enter fullscreen mode Exit fullscreen mode

✅ 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);
Enter fullscreen mode Exit fullscreen mode

✅ 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;
};
Enter fullscreen mode Exit fullscreen mode

✅ 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];
};
Enter fullscreen mode Exit fullscreen mode

✅ 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]);
};
Enter fullscreen mode Exit fullscreen mode

✅ 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;
};
Enter fullscreen mode Exit fullscreen mode

✅ 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.


Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)