Hooks and effects

Extract a small custom Hook

Move repeated stateful behavior into a named function while keeping the rendered markup in components.

A custom Hook packages reusable stateful behavior behind a clear name.

function useOnlineStatus() {
  const [online, setOnline] = useState(navigator.onLine)

  useEffect(() => {
    function handleOnline() {
      setOnline(true)
    }

    function handleOffline() {
      setOnline(false)
    }

    window.addEventListener('online', handleOnline)
    window.addEventListener('offline', handleOffline)

    return () => {
      window.removeEventListener('online', handleOnline)
      window.removeEventListener('offline', handleOffline)
    }
  }, [])

  return online
}

A component can now use the behavior without knowing the subscription details:

const online = useOnlineStatus()

Extract a custom Hook when several components need the same synchronization or state transition logic, or when a named abstraction makes one complex component easier to read.

Keep the name specific. useOnlineStatus explains a result. useStuff hides it.

A custom Hook shares logic, not one state value. Two calls have independent Hook state, although both may subscribe to the same browser source.

Do not extract every pair of useState calls. A custom Hook should create a meaningful boundary, not move code to another file without improving the model.

Use the Hook from two components and toggle offline mode in DevTools. Both should update, and removing one component should clean up only its listeners.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →