Lessons in this course (17)

10. Custom hooks and the Rules of Hooks

Intermediate★ Must knowLesson 10 of 17
jsx
function useFetch(url) {
  const [state, setState] = useState({ data: null, error: null, loading: true });
  useEffect(() => {
    const c = new AbortController();
    setState(s => ({ ...s, loading: true }));
    fetch(url, { signal: c.signal })
      .then(r => r.json())
      .then(data => setState({ data, error: null, loading: false }))
      .catch(error => { if (error.name !== "AbortError") setState({ data: null, error, loading: false }); });
    return () => c.abort();
  }, [url]);
  return state;
}

function useDebounce(value, ms = 300) {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => { const t = setTimeout(() => setDebounced(value), ms); return () => clearTimeout(t); }, [value, ms]);
  return debounced;
}

Rules of Hooks: 1) call hooks only at the top level of a component or custom hook (not in loops, conditions, nested functions or after early returns) — React relies on call order; 2) call them only from React function components or custom hooks. Custom hook names start with use. Exception: the new use() API can be called conditionally.