React · module 10 of 15
Custom Hooks & Patterns
Extract stateful logic into reusable hook functions. Must start with "use".
What this module covers
4 steps · React
Step 1. Custom Hooks & Patterns
Extract stateful logic into reusable hook functions. Must start with "use". function useLocalStorage(key, initial) { const [value, setValue] = useState(() => { try { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initial; } catch { return initial; } }); const set = useCallback((v) => { localStorage.setItem(key, JSON.stringify(v)); setValue(v); }, [key]); return [value, set]; } function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch(url).then(r => r.json()).then(setData).finally(() => setLoading(false)); }, [url]); return { data, loading }; } createPortal renders content into a DOM node outside the component's parent — useful for modals that need to escape a parent's overflow:hidden.
useToggle is the simplest possible custom hook — it doesn't need to be complex to be genuinely useful; extracting even this small a pattern avoids repeating the same three lines in every component that needs an on/off flag. In React, make the state/interaction visible in the UI so completion is easy to verify.
Check yourself: [React] Does useToggle return a boolean value and a function that flips it?
Step 2. Quiz: Custom Hooks & Patterns
Answer these questions about custom hooks and reusable patterns.
Custom hooks must start with "use" so React's rules-of-hooks tooling can recognize them, and they exist to share stateful logic between components. In React, make the state/interaction visible in the UI so completion is easy to verify.
Check yourself: [React] Answer the quiz below.
Step 3. useDebounce Hook
Create a useDebounce(value, delay) hook. Use it to debounce a search input so the search fires only 500ms after the user stops typing.
The cleanup function is what makes this a debounce and not just a delay: every keystroke cancels the previous pending timeout before starting a new one, so only the last one ever fires. In React, make the state/interaction visible in the UI so completion is easy to verify.
Check yourself: [React] Does useDebounce use useEffect with a timeout, cleaning up on every value change?
Step 4. Mini project: Custom Hooks & Patterns
Create a useDebounce(value, delay) hook. Use it to debounce a search input so the search fires only 500ms after the user stops typing. Turn the completed challenge into a small standalone project. Add realistic content, clear naming, one edge case or error state, and a short README-style explanation of how the main idea works.
The cleanup function is what makes this a debounce and not just a delay: every keystroke cancels the previous pending timeout before starting a new one, so only the last one ever fires. This project stage asks you to apply the same idea without step-by-step scaffolding. In React, make the state/interaction visible in the UI so completion is easy to verify.
Check yourself: [React] Does useDebounce use useEffect with a timeout, cleaning up on every value change?
Loading code lab...