Custom Hooks: Reuse Stateful Logic

Harry · 28 Sep 2026 · 1 views
Log in to track your progress and mark lessons complete.

Extract a Hook

function useLocalStorage(key, initial) {
  const [value, setValue] = useState(() => {
    try { return JSON.parse(localStorage.getItem(key)) ?? initial }
    catch { return initial }
  })
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value))
  }, [key, value])
  return [value, setValue]
}

useFetch in 20 Lines

function useFetch(url) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState("")
  useEffect(() => {
    let alive = true
    setLoading(true)
    fetch(url)
      .then(r => { if (!r.ok) throw new Error("HTTP " + r.status); return r.json() })
      .then(d => alive && setData(d))
      .catch(e => alive && setError(e.message))
      .finally(() => alive && setLoading(false))
    return () => { alive = false }
  }, [url])
  return { data, loading, error }
}

Hook Rules (Never Break)

  • Call hooks at the top level only - never in loops, conditions or nested functions.
  • Only call hooks from React functions or custom hooks.
  • Name custom hooks use* so lint rules apply.

Key Points

  • Custom hooks share logic, not UI.
  • One well-made useFetch replaces fetch code in every page.
  • Rules of Hooks exist so React can track call order.
Share this post:

Comments (0)

Please login or register to comment.

Create a free account to keep reading

You've enjoyed a free tutorial! Register (it's free) to unlock every tutorial, track your progress and save code.

or sign in with your account

Already have an account? Log in