Here's a list of 10 useful custom hooks that you can use in your React applications:
useLocalStorage: A hook for storing state in the browser's local storage.
import { useState } from 'react'; const useLocalStorage = (key, initialValue) => { const [value, setValue] = useState(() => { const storedValue = localStorage.getItem(key); return storedValue !== null ? JSON.parse(storedValue) : initialValue; }); const setLocalStorageValue = (newValue) => { setValue(newValue); localStorage.setItem(key, JSON.stringify(newValue)); }; return [value, setLocalStorageValue]; }; export default useLocalStorage;
useToggle: A hook for toggling between two states (e.g., true/false).
import { useState } from 'react'; const useToggle = (initialValue = false) => { const [value, setValue] = useState(initialValue); const toggleValue = () => { setValue((prevValue) => !prevValue); }; return [value, toggleValue]; }; export default useToggle;
useDebounce: A hook for debouncing the execution of a function.
import { useState, useEffect } from 'react'; const useDebounce = (value, delay) => { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; }; export default useDebounce;
useAsync: A hook for handling asynchronous operations with loading and error states.
import { useState, useEffect } from 'react'; const useAsync = (asyncFunction) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const execute = async (...args) => { try { setLoading(true); const response = await asyncFunction(...args); setData(response); } catch (error) { setError(error); } finally { setLoading(false); } }; return { data, loading, error, execute }; }; export default useAsync;
useMediaQuery: A hook for detecting changes in the viewport size.
import { useState, useEffect } from 'react'; const useMediaQuery = (query) => { const [matches, setMatches] = useState(false); useEffect(() => { const mediaQuery = window.matchMedia(query); const listener = (event) => { setMatches(event.matches); }; mediaQuery.addListener(listener); setMatches(mediaQuery.matches); return () => { mediaQuery.removeListener(listener); }; }, [query]); return matches; }; export default useMediaQuery;
usePrevious: A hook for accessing the previous value of a state or prop.
import { useRef, useEffect } from 'react'; const usePrevious = (value) => { const ref = useRef(); useEffect(() => { ref.current = value; }, [value]); return ref.current; }; export default usePrevious;
useHover: A hook for detecting hover events on an element.
import { useState, useRef, useEffect } from 'react'; const useHover = () => { const [isHovered, setIsHovered] = useState(false); const ref = useRef(null); const handleMouseOver = () => setIsHovered(true); const handleMouseOut = () => setIsHovered(false); useEffect(() => { const node = ref.current; if (node) { node.addEventListener('mouseover', handleMouseOver); node.addEventListener('mouseout', handleMouseOut); return () => { node.removeEventListener('mouseover', handleMouseOver); node.removeEventListener('mouseout', handleMouseOut); }; } }, []); return [ref, isHovered]; }; export default useHover;
useInterval: A hook for creating an interval that executes a function repeatedly.
import { useEffect, useRef } from 'react'; const useInterval = (callback, delay) => { const savedCallback = useRef(); useEffect(() => { savedCallback.current = callback; }, [callback]); useEffect(() => { const tick = () => { savedCallback.current(); }; if (delay
!== null) { const id = setInterval(tick, delay); return () => clearInterval(id); } }, [delay]); };
export default useInterval;
9. **useClickOutside:**
A hook for detecting clicks outside of a specified element.
```javascript
import { useEffect } from 'react';
const useClickOutside = (ref, callback) => {
useEffect(() => {
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
callback();
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [ref, callback]);
};
export default useClickOutside;
useKeyPress: A hook for detecting keyboard 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;
These examples show how you can make custom hooks to handle common tasks or actions in your React apps. Custom hooks help you write neater, more organized code and make it easier to use the same code in different parts of your projects.