Custom hooks extract component logic into reusable functions. Name them starting with use: useFetch, useLocalStorage, useDebounce.
useFetch pattern: manages loading, error, and data states. Accepts URL and options, returns { data, loading, error }. Uses useEffect for the fetch call and AbortController for cleanup.
useLocalStorage syncs state with localStorage: const [value, setValue] = useLocalStorage('key', initial). Handles serialization and SSR gracefully.
useDebounce delays rapid updates: const debouncedSearch = useDebounce(searchTerm, 300). Prevents excessive API calls during typing.
Other essential hooks: useMediaQuery (responsive logic), useClickOutside (close dropdowns), useEventListener (DOM events), usePrevious (access prior state).
The power of custom hooks is composition: combine multiple hooks to create complex behaviors while keeping components simple.