React · module 10 of 15

Custom Hooks & Patterns

Extract stateful logic into reusable hook functions. Must start with "use".

Course map

What this module covers

4 steps · React

  1. 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?

  2. 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.

  3. 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?

  4. 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...