TLDR 🔥
React.js is one of the most popular JavaScript libraries for building beautiful user interfaces and single-page applications. And the average salary of a react developer goes up to 100K usd a year . React is used by some of the most popular tech companies around the world. The React ecosystem is vast and has a huge number of supporting libraries and frameworks, which give React additional powers to build full-stack, production-grade applications. The key features of React include component-driven architecture, the use of a virtual DOM, one-way data binding, and many more. However, in this particular article, I will focus on one of the most important features of React: hooks. I will explain the concept of hooks in detail.
- What are react hooks and their importance
- 38 react hooks you must know as a react developer along with code
What are hooks in react and their importance?
Hooks in React allow developers to use the state of a React application without using classes. This helps React developers write clean and reusable components with fewer lines of code. Knowledge of React hooks will help you excel in React interviews, as it is one of the most important topics asked by interviewers in every React interview.
The top 38 react hooks
1. useState
Manages local component state.
import { useState } from ‘react’;
function Counter() { const [count, setCount] = useState(0); return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button>
<p>Count: {count}</p>
</div>
);
}
2. useEffect
Performs side effects in function components.
import { useEffect, useState } from 'react'; function DataFetcher() { const [data, setData] = useState(null); useEffect(() => { fetch('https://api.example.com/data') .then(response => response.json()) .then(data => setData(data)); }, []); return <div>Data: {data ? JSON.stringify(data) : 'Loading...'}</div>;
}
3. useContext
Consumes context in a component.
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; function ThemedButton() { const theme = useContext(ThemeContext); return <button style={{ background: theme.background }}>Click me</button>;
}
4.useReducer
Manages complex state logic
import { useReducer } from 'react'; const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); }
} function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<span>{state.count}</span>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</div>
);
}
5. useCallback
Returns a memoized callback function.
import { useCallback, useState } from 'react'; function CallbackComponent() { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount(count + 1); }, [count]); return <button onClick={increment}>Count: {count}</button>;
}
- useMemo
Memoizes expensive calculations.
import { useMemo, useState } from 'react'; function Fibonacci() { const [num, setNum] = useState(1); const fib = useMemo(() => { const computeFib = (n) => (n <= 1 ? n : computeFib(n - 1) + computeFib(n - 2)); return computeFib(num); }, [num]); return ( <div> <button onClick={() => setNum(num + 1)}>Next Fibonacci</button>
<p>Fibonacci of {num} is {fib}</p>
</div>
);
}
7.useRef
Accesses DOM elements or stores mutable values.
import { useRef } from 'react'; function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { inputEl.current.focus(); }; return ( <div> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus the input</button>
</div>
);
}
8.useImperativeHandle
Customizes the instance value exposed by a ref.
import { forwardRef, useImperativeHandle, useRef } from 'react'; const FancyInput = forwardRef((props, ref) => { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); }, })); return <input ref={inputRef} />;
}); function App() { const fancyInputRef = useRef(); return ( <div> <FancyInput ref={fancyInputRef} />
<button onClick={() => fancyInputRef.current.focus()}>Focus input</button>
</div>
);
}
9. useLayoutEffect
Synchronizes with the DOM layout.
import { useEffect, useLayoutEffect, useRef, useState } from 'react'; function MeasureWidth() { const ref = useRef(); const [width, setWidth] = useState(0); useLayoutEffect(() => { setWidth(ref.current.offsetWidth); }, []); return ( <div> <div ref={ref} style={{ width: '50%' }}> Resize the window to see the effect. </div>
<p>Width: {width}px</p>
</div>
);
}
10.useDebugValue
Displays custom label in React DevTools.
import { useDebugValue, useState } from 'react'; function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); useDebugValue(isOnline ? 'Online' : 'Offline'); // Simulate an asynchronous operation setTimeout(() => setIsOnline(Math.random() > 0.5), 1000); return isOnline;
} function FriendStatus({ friendID }) { const isOnline = useFriendStatus(friendID); if (isOnline === null) { return 'Loading...'; } return isOnline ? 'Online' : 'Offline';
}
11.useFetch
Fetches data from an API.
import { useEffect, useState } from 'react'; function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch(url) .then(response => response.json()) .then(data => { setData(data); setLoading(false); }); }, [url]); return { data, loading };
} function App() { const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts'); if (loading) { return <p>Loading...</p>;
} return ( <ul> {data.map(post => ( <li key={post.id}>{post.title}</li>
))} </ul>
);
}
12.useLocalStorage
Manages state with local storage.
import { useState } from 'react'; function useLocalStorage(key, initialValue) { const [storedValue, setStoredValue] = useState(() => { try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { console.error(error); return initialValue; } }); const setValue = (value) => { try { const valueToStore = value instanceof Function ? value(storedValue) : value; setStoredValue(valueToStore); window.localStorage.setItem(key, JSON.stringify(valueToStore)); } catch (error) { console.error(error); } }; return [storedValue, setValue];
} function App() { const [name, setName] = useLocalStorage('name', 'Bob'); return ( <div> <input value={name} onChange={(e) => setName(e.target.value)} />
<p>Hello, {name}!</p>
</div>
);
}
13. useDebounce
Debounces a value over time.
import { useEffect, useState } from 'react'; function useDebounce(value, delay) { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue;
} function App() { const [text, setText] = useState(''); const debouncedText = useDebounce(text, 500); return ( <div> <input value={text} onChange={(e) => setText(e.target.value)} />
<p>Debounced Value: {debouncedText}</p>
</div>
);
}
14.usePrevious
Stores the previous value of a variable.
import { useEffect, useRef } from 'react'; function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }, [value]); return ref.current;
} function App() { const [count, setCount] = useState(0); const previousCount = usePrevious(count); return ( <div> <button onClick={() => setCount(count + 1)}>Count: {count}</button>
<p>Previous Count: {previousCount}</p>
</div>
);
}
15. useWindowSize
Tracks window size.
import { useEffect, useState } from 'react'; function useWindowSize() { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight }); useEffect(() => { const handleResize = () => { setSize({ width: window.innerWidth, height: window.innerHeight }); }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return size;
} function App() { const { width, height } = useWindowSize(); return ( <div> <p>Width: {width}px</p>
<p>Height: {height}px</p>
</div>
);
}
16.useHover
Detects if an element is hovered.
import { useCallback, useState } from 'react'; function useHover() { const [hovered, setHovered] = useState(false); const onMouseOver = useCallback(() => setHovered(true), []); const onMouseOut = useCallback(() => setHovered(false), []); return { hovered, onMouseOver, onMouseOut };
} function HoverComponent() { const { hovered, onMouseOver, onMouseOut } = useHover(); return ( <div onMouseOver={onMouseOver} onMouseOut={onMouseOut}> {hovered ? 'Hovering' : 'Not Hovering'} </div>
);
}
17. useOnlineStatus
Tracks online status.
import { useEffect, useState } from 'react'; function 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;
} function App() { const isOnline = useOnlineStatus(); return <div>{isOnline ? 'Online' : 'Offline'}</div>;
}
18. useEventListener
Attaches an event listener.
import { useEffect, useRef } from 'react'; function useEventListener(eventName, handler, element = window) { const savedHandler = useRef(); useEffect(() => { savedHandler.current = handler; }, [handler]); useEffect(() => { const eventListener = (event) => savedHandler.current(event); element.addEventListener(eventName, eventListener); return () => { element.removeEventListener(eventName, eventListener); }; }, [eventName, element]);
} function App() { useEventListener('click', () => alert('Window clicked!')); return <div>Click anywhere!</div>;
}
19.useInterval
Sets up an interval with a dynamic delay.
import { useEffect, useRef } from 'react'; function useInterval(callback, delay) { const savedCallback = useRef(); useEffect(() => { savedCallback.current = callback; }, [callback]); useEffect(() => { function tick() { savedCallback.current(); } if (delay !== null) { const id = setInterval(tick, delay); return () => clearInterval(id); } }, [delay]);
} function Timer() { const [count, setCount] = useState(0); useInterval(() => setCount(count + 1), 1000); return <div>Count: {count}</div>;
}
20. useTimeout
Sets up a timeout.
import { useEffect, useRef } from 'react'; function useTimeout(callback, delay) { const savedCallback = useRef(); useEffect(() => { savedCallback.current = callback; }, [callback]); useEffect(() => { function tick() { savedCallback.current(); } if (delay !== null) { const id = setTimeout(tick, delay); return () => clearTimeout(id); } }, [delay]);
} function App() { const [visible, setVisible] = useState(true); useTimeout(() => setVisible(false), 5000); return <div>{visible ? 'Visible for 5 seconds' : 'Hidden'}</div>;
}
21. useOnClickOutside
Detects clicks outside a component.
import { useEffect, useRef } from 'react'; function useOnClickOutside(ref, handler) { useEffect(() => { const listener = (event) => { if (!ref.current || ref.current.contains(event.target)) { return; } handler(event); }; document.addEventListener('mousedown', listener); document.addEventListener('touchstart', listener); return () => { document.removeEventListener('mousedown', listener); document.removeEventListener('touchstart', listener); }; }, [ref, handler]);
} function App() { const ref = useRef(); const [isVisible, setIsVisible] = useState(true); useOnClickOutside(ref, () => setIsVisible(false)); return ( <div> <div ref={ref} style={{ display: isVisible ? 'block' : 'none' }}> Click outside this box to hide it. </div>
</div>
);
}
22. useClipboard
Handles clipboard operations.
import { useState } from 'react'; function useClipboard() { const [copied, setCopied] = useState(false); const copy = (text) => { navigator.clipboard.writeText(text).then(() => setCopied(true)); }; return { copied, copy };
} function App() { const { copied, copy } = useClipboard(); return ( <div> <button onClick={() => copy('Hello, world!')}> {copied ? 'Copied!' : 'Copy'} </button>
</div>
);
}
23. useDarkMode
Manages dark mode preference.
import { useEffect, useState } from 'react'; function useDarkMode() { const [isDarkMode, setIsDarkMode] = useState(false); useEffect(() => { const darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; setIsDarkMode(darkMode); }, []); return isDarkMode;
} function App() { const isDarkMode = useDarkMode(); return <div>{isDarkMode ? 'Dark Mode' : 'Light Mode'}</div>;
}
24.useToggle
Toggles between boolean values.
import { useState } from 'react'; function useToggle(initialValue = false) { const [value, setValue] = useState(initialValue); const toggle = () => setValue(!value); return [value, toggle];
} function App() { const [isToggled, toggle] = useToggle(); return ( <div> <button onClick={toggle}>{isToggled ? 'On' : 'Off'}</button>
</div>
);
}
25. useTheme
Toggles between light and dark themes.
import { useEffect, useState } from 'react'; function useTheme() { const [theme, setTheme] = useState('light'); useEffect(() => { document.body.className = theme; }, [theme]); const toggleTheme = () => { setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); }; return { theme, toggleTheme };
} function App() { const { theme, toggleTheme } = useTheme(); return ( <div> <p>Current Theme: {theme}</p>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}
26. useMedia
Queries media properties.
import { useEffect, useState } from 'react'; function useMedia(query) { const [matches, setMatches] = useState(window.matchMedia(query).matches); useEffect(() => { const mediaQueryList = window.matchMedia(query); const listener = (event) => setMatches(event.matches); mediaQueryList.addListener(listener); return () => mediaQueryList.removeListener(listener); }, [query]); return matches;
} function App() { const isLargeScreen = useMedia('(min-width: 800px)'); return <div>{isLargeScreen ? 'Large Screen' : 'Small Screen'}</div>;
}
27. useLockBodyScroll
Locks the body scroll.
import { useEffect } from 'react'; function useLockBodyScroll() { useEffect(() => { const originalOverflow = window.getComputedStyle(document.body).overflow; document.body.style.overflow = 'hidden'; return () => (document.body.style.overflow = originalOverflow); }, []);
} function App() { useLockBodyScroll(); return <div>Body scroll is locked</div>;
}
28.useKeyPress
Detects key press.
import { useEffect, useState } from 'react'; function useKeyPress(targetKey) { const [keyPressed, setKeyPressed] = useState(false); useEffect(() => { const downHandler = ({ key }) => { if (key === targetKey) setKeyPressed(true); }; const upHandler = ({ key }) => { if (key === targetKey) setKeyPressed(false); }; window.addEventListener('keydown', downHandler); window.addEventListener('keyup', upHandler); return () => { window.removeEventListener('keydown', downHandler); window.removeEventListener('keyup', upHandler); }; }, [targetKey]); return keyPressed;
} function App() { const aPressed = useKeyPress('a'); return <div>{aPressed ? 'A is pressed' : 'Press A'}</div>;
}
29. useDocumentTitle
Updates document title.
import { useEffect } from 'react'; function useDocumentTitle(title) { useEffect(() => { document.title = title; }, [title]);
} function App() { useDocumentTitle('Custom Title'); return <div>Check the document title</div>;
}
30. useHover
Handles hover state.
import { useCallback, useState } from 'react'; function useHover() { const [hovered, setHovered] = useState(false); const onMouseOver = useCallback(() => setHovered(true), []); const onMouseOut = useCallback(() => setHovered(false), []); return { hovered, onMouseOver, onMouseOut };
} function HoverComponent() { const { hovered, onMouseOver, onMouseOut } = useHover(); return ( <div onMouseOver={onMouseOver} onMouseOut={onMouseOut}> {hovered ? 'Hovering' : 'Not Hovering'} </div>
);
}
31.useGeolocation
Retrieves geolocation.
import { useEffect, useState } from 'react'; function useGeolocation() { const [location, setLocation] = useState({}); useEffect(() => { navigator.geolocation.getCurrentPosition( (position) => setLocation(position.coords), (error) => console.error(error) ); }, []); return location;
} function App() { const { latitude, longitude } = useGeolocation(); return ( <div> <p>Latitude: {latitude}</p>
<p>Longitude: {longitude}</p>
</div>
);
}
32. useScrollPosition
Tracks scroll position.
import { useEffect, useState } from 'react'; function useScrollPosition() { const [position, setPosition] = useState({ x: 0, y: 0 }); useEffect(() => { const handleScroll = () => { setPosition({ x: window.scrollX, y: window.scrollY }); }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); return position;
} function App() { const { x, y } = useScrollPosition(); return ( <div> <p>Scroll Position: {`x: ${x}, y: ${y}`}</p>
</div>
);
}
33. useUnmount
Runs a function when a component unmounts.
import { useEffect } from 'react'; function useUnmount(callback) { useEffect(() => { return () => callback(); }, [callback]);
} function App() { useUnmount(() => { console.log('Component will unmount'); }); return <div>Unmount me to see the console message.</div>;
}
34. useClickOutside
Detects clicks outside an element.
import { useEffect, useRef } from 'react'; function useClickOutside(handler) { const ref = useRef(); useEffect(() => { const listener = (event) => { if (!ref.current || ref.current.contains(event.target)) { return; } handler(event); }; document.addEventListener('mousedown', listener); document.addEventListener('touchstart', listener); return () => { document.removeEventListener('mousedown', listener); document.removeEventListener('touchstart', listener); }; }, [handler]); return ref;
} function App() { const handleClickOutside = () => { console.log('Clicked outside!'); }; const ref = useClickOutside(handleClickOutside); return ( <div ref={ref} style={{ padding: '50px', border: '1px solid black' }}> Click outside me! </div>
);
}
35. useDebouncedCallback
Debounces a callback function.
import { useCallback, useState } from 'react'; function useDebouncedCallback(callback, delay) { const [timeoutId, setTimeoutId] = useState(null); const debouncedCallback = useCallback((...args) => { if (timeoutId) { clearTimeout(timeoutId); } const id = setTimeout(() => { callback(...args); }, delay); setTimeoutId(id); }, [callback, delay]); return debouncedCallback;
} function App() { const [value, setValue] = useState(''); const handleChange = useDebouncedCallback((e) => { setValue(e.target.value); }, 500); return ( <input type="text" onChange={handleChange} />
);
}
36. useThrottle
Throttles a value over time.
import { useEffect, useState } from 'react'; function useThrottle(value, limit) { const [throttledValue, setThrottledValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setThrottledValue(value); }, limit); return () => { clearTimeout(handler); }; }, [value, limit]); return throttledValue;
} function App() { const [text, setText] = useState(''); const throttledText = useThrottle(text, 1000); return ( <div> <input value={text} onChange={(e) => setText(e.target.value)} />
<p>Throttled Value: {throttledText}</p>
</div>
);
}
37. useUpdateEffect
Runs an effect only on updates, not on mount.
import { useEffect, useRef } from 'react'; function useUpdateEffect(effect, dependencies) { const isInitialMount = useRef(true); useEffect(() => { if (isInitialMount.current) { isInitialMount.current = false; } else { effect(); } }, dependencies);
} function App() { const [count, setCount] = useState(0); useUpdateEffect(() => { console.log('Component updated'); }, [count]); return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button>
<p>Count: {count}</p>
</div>
);
}
38.useLocalStorage
Manages state in local storage
import { useEffect, useState } from 'react'; function useLocalStorage(key, initialValue) { const [storedValue, setStoredValue] = useState(() => { try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { console.error(error); return initialValue; } }); const setValue = (value) => { try { setStoredValue(value); window.localStorage.setItem(key, JSON.stringify(value)); } catch (error) { console.error(error); } }; return [storedValue, setValue];
} function App() { const [name, setName] = useLocalStorage('name', 'Guest'); return ( <div> <input value={name} onChange={(e) => setName(e.target.value)} />
</div>
);
}
conclusion
In this article you learned about the top 38 react hooks and their use cases. Make sure to use these hooks in you code and stay tuned for the next article.
Discover more from Coursity
Subscribe to get the latest posts sent to your email.