Congratulations on preparing for your intermediate React Hooks interview! This guide will help you master core concepts, ace common questions, write clean code, and adopt best practices. Let’s dive in!
Hooks let you use state and other React features in functional components. They were introduced in React 16.8 to eliminate class components’ complexity.
| Hook | Purpose | Key Points |
|---|---|---|
useState | Manage local state in functional components | initializer runs once; updates trigger re-renders. Use objects/arrays carefully (spread syntax). |
useEffect | Handle side effects (HTTP requests, subscriptions, timers) | Similar to componentDidMount, componentDidUpdate, and componentWillUnmount combined. Dependency array controls execution. |
useContext | Access React Context without prop drilling | Passes context value down the tree. Use for shared state (e.g., themes, auth). |
useReducer | Manage complex state logic (alternative to useState) | Ideal for state that’s interrelated or requires reducing functions. |
useMemo | Memoize expensive calculations | Prevents recalculation on every render. Depends on dependencies. |
useCallback | Memoize functions passed as props | Prevents unnecessary re-renders of child components. |
useRef | Access DOM nodes or preserve values between renders | ref.current is mutable; doesn’t trigger re-renders. |
useImperativeHandle | Customize the instance returned by ref | Used rarely; for exposing methods to parent components. |
useLayoutEffect | Effect that runs synchronously after DOM mutation (like componentDidUpdate) | Similar to useEffect but Before Paint. |
useEffect and componentDidMount.useEffect:
useEffect(() => { // Runs after mount *and* on updates }, []); // Empty array = runs **only after mount** (similar to `componentDidMount`)
componentDidMount: Only runs once after initial render (no dependency control).Key Point: useEffect with an empty dependency array mimics componentDidMount, but cleanup works like componentWillUnmount.
useEffect?It determines when the effect runs:
[]: Runs once after initial render.[a, b]: Runs when a or b change.Common Pitfall: Missing dependencies leads to stale closures or unwanted side effects.
useMemo and useCallback?| Hook | Purpose | Example |
|---|---|---|
useMemo | Memoize values (e.g., computed data) | const memoizedValue = useMemo(() => compute(a, b), [a, b]); |
useCallback | Memoize functions (callbacks) | const handleClick = useCallback(() => doSomething(a), [a]); |
useReducer over useState?Use useReducer when:
dispatch actions.Example:
const [state, dispatch] = useReducer((state, action) => { switch (action.type) { case 'INCREMENT': return { count: state.count + 1 }; default: return state; } }, { count: 0 });
A custom Hook is a function that uses other Hooks and encapsulates reusable logic.
Benefits:
Example:
// useLocalStorage.js export default function useLocalStorage(key, initialValue) { const [value, setValue] = useState(() => { const storedValue = localStorage.getItem(key); return storedValue ? JSON.parse(storedValue) : initialValue; }); useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue]; }
useEffectimport { useState, useEffect } from 'react'; function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { const res = await fetch('https://api.example.com/users'); const data = await res.json(); setUsers(data); setLoading(false); }; fetchData(); // Cleanup (optional): return () => { // Cancel pending requests if component unmounts }; }, []); if (loading) return <p>Loading...</p>; return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
useCallback and useEffectfunction SearchInput() { const [query, setQuery] = useState(''); const [debouncedQuery, setDebouncedQuery] = useState(query); // Debounce logic using useEffect useEffect(() => { const timer = setTimeout(() => { setDebouncedQuery(query); }, 500); return () => clearTimeout(timer); }, [query]); // Memoized search function const handleSearch = useCallback(() => { console.log('Searching for:', debouncedQuery); // API call here }, [debouncedQuery]); return ( <div> <input type="text" value={query} onChange={(e) => setQuery(e.target.value)} /> <button onClick={handleSearch}>Search</button> </div> ); }
useEffect/useMemo to avoid unnecessary runs.useRef for mutable values that don’t trigger re-renders (e.g., timers, DOM refs).useReducer for state that requires multiple update steps.react-hooks/exhaustive-deps).useState – use references or useRef instead.React.memo for components receiving memoized props (useCallback/useMemo).useState vs. useReducer vs. Context.You’ve got this! 💪 Remember: understand the “why” behind each Hook, and you’ll ace the interview!
Start a new session to explore different topics or increase the difficulty level.
Start New Session