Blog/NotesConcept

20 Most Asked Custom Hooks In React for Interviews

Explore the Most Common Custom Hooks in React asked in the React Interviews. It includes the code example of all the custom hooks in react for a quick revision before interview.

Intermediate

Anuj Sharma

Last Updated Jun 11, 2026


20 Most Asked Custom Hooks In React for Interviews

Custom hooks improve the overall reusability in the react application and reduce down the boilerplate code. Understanding custom hooks are so important that Nowadays Custom Hooks in React are one of the most asked React Interviews questions.

Any number of custom hooks can be make as per the requirement, so to help you out we have captured the 20 most asked Custom Hooks in React with code implementation for quick revision before your frontend interview

Table of content

  1. useFetch() Hook
  2. useToggle() Hook
  3. useTheme() Hook
  4. usePrefersColorScheme() Hook
  5. useLocalStorage() Hook
  6. useSessionStorage() Hook
  7. useDebounce() Hook
  8. useThrottle() Hook
  9. useIntersectionObserver() Hook
  10. usePrevious() Hook
  11. useOnClickOutside() Hook
  12. useCopyToClipboard() Hook
  13. useInfiniteScroll() Hook
  14. useDocumentTitle() Hook
  15. usePolling() Hook
  16. useOnlineStatus() Hook
  17. useScrollPosition() Hook
  18. useKeyPress() Hook
  19. useMediaQuery() Hook
  20. useWindowSize() Hook

1. useFetch() Hook

The useFetch hook in react is used for making HTTP requests in React components, and handle the loading, error states better.

import { useState, useEffect } from 'react';

const useFetch = (url) => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const fetchData = async () => {
            const response = await fetch(url);
            const result = await response.json();
            setData(result);
            setLoading(false);
        };

        fetchData();
    }, [url]);

    return { data, loading };
};

export default useFetch;

Detailed useFetch Hook Guide →

2. useToggle() Hook

The useToggle hook is used to toggle between two states.

import { useState } from 'react';

const useToggle = (initialState = false) => {
    const [state, setState] = useState(initialState);

    const toggle = () => {
        setState(!state);
    };

    return [state, toggle];
};

export default useToggle;

Detailed useToggle Hook Guide →

3. useTheme() Hook

The useTheme hook is used for managing themes in a React application.

import { useState } from 'react';

const useTheme = () => {
    const [theme, setTheme] = useState('light');

    const toggleTheme = () => {
        setTheme(theme === 'light' ? 'dark' : 'light');
    };

    return [theme, toggleTheme];
};

export default useTheme;

Detailed useTheme Hook Guide

4. usePrefersColorScheme() Hook

The usePrefersColorScheme hook is used to detect the user's preferred color scheme.

import { useState, useEffect } from 'react';

const usePrefersColorScheme = () => {
    const [colorScheme, setColorScheme] = useState('light');

    useEffect(() => {
        const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
        setColorScheme(mediaQuery.matches ? 'dark' : 'light');
    }, []);

    return colorScheme;
};

export default usePrefersColorScheme;

5. useLocalStorage() Hook

The useLocalStorage hook is used to persist state in local storage.

import { useState } from 'react';

const useLocalStorage = (key, initialValue) => {
    const [value, setValue] = useState(() => {
        const storedValue = localStorage.getItem(key);
        return storedValue ? JSON.parse(storedValue) : initialValue;
    });

    const setStoredValue = (newValue) => {
        setValue(newValue);
        localStorage.setItem(key, JSON.stringify(newValue));
    };

    return [value, setStoredValue];
};

export default useLocalStorage;

Detailed useLocalStorage Hook Guide →

6. useSessionStorage() Hook

The useSessionStorage hook is similar to useLocalStorage but interacts with session storage instead.

// Implementation of useSessionStorage
const useSessionStorage = (key, initialValue) => {
  const [storedValue, setStoredValue] = useState(() => {
    const item = window.sessionStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  const setValue = value => {
    setStoredValue(value);
    window.sessionStorage.setItem(key, JSON.stringify(value));
  };

  return [storedValue, setValue];
};

Detailed useSessionStorage Hook Guide →

7. useDebounce() Hook

The useDebounce hook delays the execution of a function until a specified time has elapsed since the last invocation.

// Implementation of useDebounce
const useDebounce = (value, delay) => {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
};

Detailed useDebounce Hook Guide →

8. useThrottle() Hook

The useThrottle hook limits the rate at which a function is executed.

// Implementation of useThrottle
const useThrottle = (value, delay) => {
  const [throttledValue, setThrottledValue] = useState(value);
  const lastExecTime = useRef(0);

  useEffect(() => {
    const now = Date.now();
    if (now - lastExecTime.current > delay) {
      setThrottledValue(value);
      lastExecTime.current = now;
    }
  }, [value, delay]);

  return throttledValue;
};

Detailed useThrottle Hook Guide →

9. useIntersectionObserver() Hook

Custom hook to observe when an element enters or exits the viewport.

import { useEffect, useRef, useState } from 'react';

const useIntersectionObserver = (target, options) => {
    const [isVisible, setIsVisible] = useState(false);
    const observer = useRef(new IntersectionObserver(
        ([entry]) => setIsVisible(entry.isIntersecting),
        options
    ));

    useEffect(() => {
        observer.current.observe(target);
        return () => observer.current.disconnect();
    }, [target]);

    return isVisible;
};

export default useIntersectionObserver;

Detailed useIntersectionObserver Hook Guide

10. usePrevious() Hook

Custom hook to store the previous value of a state variable.

import { useEffect, useRef } from 'react';

const usePrevious = (value) => {
    const ref = useRef();
    useEffect(() => {
        ref.current = value;
    });
    return ref.current;
};

export default usePrevious;

Detailed usePrevious Hook Guide →

11. useOnClickOutside() Hook

The useOnClickOutside hook is used to detect clicks that occur outside a specified element. This is commonly used for implementing dropdowns, modals, or any component that needs to close when a user clicks outside of it.

import { useEffect } from 'react';

const useOnClickOutside = (ref, handler) => {
  useEffect(() => {
    const listener = (event) => {
      if (!ref.current || ref.current.contains(event.target)) {
        return;
      }
      handler(event);
    };
    document.addEventListener('mousedown', listener);
    return () => {
      document.removeEventListener('mousedown', listener);
    };
  }, [ref, handler]);
};

// Usage
// const ref = useRef();
// useOnClickOutside(ref, () => {
//   // Close the dropdown or modal
// });

Detailed useOnClickOutside Hook Guide →

12. useCopyToClipboard() Hook

The useCopyToClipboard hook is used for copying text to the clipboard. It provides a convenient way to implement copy functionality in your React components.

const useCopyToClipboard = () => {
  const copyToClipboard = (text) => {
    navigator.clipboard.writeText(text)
      .then(() => {
        console.log('Text copied to clipboard');
      })
      .catch((error) => {
        console.error('Failed to copy text to clipboard:', error);
      });
  };

  return { copyToClipboard };
};

// Usage
// const { copyToClipboard } = useCopyToClipboard();
// copyToClipboard('Text to be copied');

Detailed useCopyToClipboard Hook Guide →

13. useInfiniteScroll() Hook

The useInfiniteScroll hook allows you to handle the large list where data is populated (locally or from server using API call) dynamically while user scrolls and hit the bottom of the page (or Intersection point).

IntersectionObserver API can be used to implement this custom hook and This react hook can be useful for building application involving large amount of data to showcase in a lazy loaded fashion. Example - Catalog page of an e-commerce application.

const useInfiniteScroll = (callback) => {
    const observer = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting) {
            callback();
        }
    });

    useEffect(() => {
        observer.observe(document.getElementById('infinite-scroll-trigger'));

        return () => {
            observer.disconnect();
        };
    }, []);
};

Detailed useInfiniteScroll Hook Guide →

14. useDocumentTitle() Hook

The useDocumentTitle hook allows you to dynamically set the document title based on the state of your component. This can be useful for updating the title of your web application based on the content being displayed.

import { useEffect } from 'react';

const useDocumentTitle = (title) => {
  useEffect(() => {
    document.title = title;
  }, [title]);
};

// Usage
// useDocumentTitle('Page Title');

Detailed useDocumentTitle Hook Guide →

15. usePolling() Hook

usePolling custom hook allows you to fetch data from an API endpoint at regular intervals. This is a useful custom hook to reuse the polling logic as part of the custom hook.

import React, { useState, useEffect } from 'react';

const usePolling = (url, interval) => {
    const [data, setData] = useState(null);

    const fetchData = async () => {
        try {
            const response = await fetch(url);
            const jsonData = await response.json();
            setData(jsonData);
        } catch (error) {
            console.error('Error fetching data:', error);
        }
    };

    useEffect(() => {
        fetchData();

        const pollingId = setInterval(() => {
            fetchData();
        }, interval);

        return () => {
            clearInterval(pollingId);
        };
    }, [url, interval]);

    return data;
};

export default usePolling;

Detailed usePolling Hook Guide →

16. useOnlineStatus() Hook

The useOnlineStatus custom hook is used to track the online status of the user's browser. This can be useful for showing a message when the user is offline or for handling network-related features.

import { useState, useEffect } from 'react';

const useOnlineStatus = () => {
    const [isOnline, setIsOnline] = useState(navigator.onLine);

    useEffect(() => {
        const handleOnline = () => setIsOnline(true);
        const handleOffline = () => setIsOnline(false);

        window.addEventListener('online', handleOnline);
        window.addEventListener('offline', handleOffline);

        return () => {
            window.removeEventListener('online', handleOnline);
            window.removeEventListener('offline', handleOffline);
        };
    }, []);

    return isOnline;
};

export default useOnlineStatus;

Detailed useOnlineStatus Hook Guide →

17. useScrollPosition() Hook

The useScrollPosition custom hook is used to track the scroll position of the page. This can be handy for implementing effects based on scroll position, such as sticky headers or lazy loading content.

import { useState, useEffect } from 'react';

const useScrollPosition = () => {
    const [scrollPosition, setScrollPosition] = useState(window.scrollY);

    useEffect(() => {
        const handleScroll = () => {
            setScrollPosition(window.scrollY);
        };

        window.addEventListener('scroll', handleScroll);

        return () => {
            window.removeEventListener('scroll', handleScroll);
        };
    }, []);

    return scrollPosition;
};

export default useScrollPosition;

Detailed useScrollPosition Hook Guide →

18. useKeyPress() Hook

The useKeyPress custom hook is used to detect when a specific key is pressed. This can be used for implementing keyboard shortcuts or handling user input based on key presses.

import { useState, useEffect } from 'react';

const useKeyPress = (targetKey) => {
    const [keyPressed, setKeyPressed] = useState(false);

    const downHandler = ({ key }) => {
        if (key === targetKey) {
            setKeyPressed(true);
        }
    };

    const upHandler = ({ key }) => {
        if (key === targetKey) {
            setKeyPressed(false);
        }
    };

    useEffect(() => {
        window.addEventListener('keydown', downHandler);
        window.addEventListener('keyup', upHandler);

        return () => {
            window.removeEventListener('keydown', downHandler);
            window.removeEventListener('keyup', upHandler);
        };
    }, [targetKey]);

    return keyPressed;
};

export default useKeyPress;

Detailed useKeyPress Hook Guide →

19. useMediaQuery() Hook

The useMediaQuery custom hook is used to track the match of a CSS media query. This can be useful for implementing responsive designs and adapting components based on screen size or device type.

import { useState, useEffect } from 'react';

const useMediaQuery = (query) => {
    const [matches, setMatches] = useState(false);

    useEffect(() => {
        const mediaQuery = window.matchMedia(query);
        setMatches(mediaQuery.matches);

        const handler = (event) => setMatches(event.matches);

        mediaQuery.addListener(handler);

        return () => {
            mediaQuery.removeListener(handler);
        };
    }, [query]);

    return matches;
};

export default useMediaQuery;

Detailed useMediaQuery Hook Guide →

20. useWindowSize() Hook

useWindowSize lets you reactively track the browser window dimensions, useful for responsive UIs, conditionally rendering layouts, or adapting components based on screen size.

import { useState, useEffect } from "react";

function useWindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    function handleResize() {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }

    // Add event listener
    window.addEventListener("resize", handleResize);

    // Call handler immediately so state is up to date
    handleResize();

    // Clean up listener on unmount
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  return windowSize;
}

Detailed useWindowSize Hook Guide →

Thats It !!

Thanks for going through all of these custom hooks in React. These hooks cover all  most important patterns to implement the custom hooks. Even if there is any other custom hook implementation comes in the interview, you will be able to implement any new custom hooks based on the knowledge of the above 20 custom hooks in react.

Happy Coding :)

Further Reading 🚀

  1. 100+ Top React JS Interview Questions and Answers
  2. Best Resources for React Interview Preparation

Love this Blog? Share it Now!

Help others discover this resource

About the Author

Anuj Sharma

A seasoned Sr. Engineering Manager at GoDaddy (Ex-Dell) with over 12+ years of experience in the frontend technologies. A frontend tech enthusiast passionate building SaaS application to solve problem. Know more about me  🚀


Learn Next

Featured

100+ Top React JS Interview Questions And Answers

Top 10 React Performance Optimization TechniquesBest React Preparation ResourcesMastering React Rendering: memo and useCallbackImplement Custom useIntersectionObserver Hook in React

Comments

Be the first to share your thoughts!

Guest User

Please login to comment

0 characters


No comments yet.

Start the conversation!

About the Author

Anuj Sharma

A seasoned Sr. Engineering Manager at GoDaddy (Ex-Dell) with over 12+ years of experience in the frontend technologies. A frontend tech enthusiast passionate building SaaS application to solve problem. Know more about me  🚀

Share your expertise

Publish a blog or quick notes on topics you know well — your write-up could be the answer someone needs before their next frontend interview.

Build your portfolio

Help the community

Sharpen your skills

Earn goodies

Other Related Blogs

20+ Frontend Machine Coding Round Interview Questions

Anuj Sharma

Last Updated Jun 9, 2026

A detailed list of 20+ most asked Frontend Machine Coding Round Interview Questions and resources both in JavaScript & React, also covers expected functional/Non-functional requirements.

React Hook Rules: Why hooks declarations are not allowed inside functions

Frontendgeek

Last Updated Feb 6, 2026

A quick guide to explain an important react interview question, why React Hooks declarations are not allowed inside functions or any conditional blocks with code example.

4 Ways to Reverse a String in JavaScript (JavaScript Interview)

Anuj Sharma

Last Updated Jun 15, 2026

Explore the most common ways to reverse a string in javascript including the most optimal way for frontend interviews with O(1) time complexity.

useState vs useReducer in React: Understand the Difference & Trade-Off

Anuj Sharma

Last Updated Jun 17, 2026

Explore useState vs useReducer in React with examples. Learn key differences, use cases, advantages, disadvantages, and when to choose one over the other in React applications and interviews.

Stay Updated

Subscribe to FrontendGeek Hub for frontend interview preparation, interview experiences, curated resources and roadmaps.

FrontendGeek
FrontendGeek

All in One Preparation Hub to Ace Frontend Interviews. Master JavaScript, React, System Design, and more with curated resources.

Consider Supporting this Free Platform

Buy Me a Coffee

Product

HomeFrontend InterviewFrontend JobsQuestionsNewInterview ExperienceBlogsToolsLeaderboardFrontendGeek Chrome extensionGet the extension on the Chrome Web Store →

© 2026 FrontendGeek. All rights reserved