Jamie Balfour

Welcome to my personal website.

Find out more about me, my personal projects, reviews, courses and much more here.

Part 6.1Reusing logic with custom Hooks

A custom Hook is a function whose name begins with use and that may call other Hooks. It extracts stateful behaviour without adding another element to the rendered tree.

Extract a custom Hook

JavaScript
import { useEffect } from "react";

export function useDocumentTitle(title) {
  useEffect(() => {
    const previousTitle = document.title;
    document.title = title;
    return () => { document.title = previousTitle; };
  }, [title]);
}

A component can now call useDocumentTitle(`${remaining} tasks remaining`). The Hook's name communicates the synchronisation and keeps its setup and cleanup together.

Logic, not state

Each call to a custom Hook has independent state. Hooks share the recipe for behaviour, not one stored value. To share the same state between components, lift it to a common owner or provide it through context.

Designing Hooks

Keep a Hook focused on one purpose and return the smallest useful interface. Avoid lifecycle-shaped names such as useMount; name the external process or user concept so callers understand why it exists.

What extraction changes

Before extraction, the component owns the Effect code. Afterwards, the component calls a function during rendering, and that custom Hook calls useEffect in the same order on every render. React still owns the Effect lifecycle; the Hook only packages the rules and dependencies behind a meaningful name.

Parameters are reactive values. When title changes, the Effect inside the Hook receives a changed dependency and synchronises the document title again.

Challenge: create useOnlineStatus

Extract the online-status behaviour from the previous lesson into useOnlineStatus.js. Return a boolean and use it in two different components.

Check your understanding

Each component call creates its own subscription and state. You reused logic, not a single shared boolean. Consider whether one shared provider would be more appropriate if many components need the value.

Feedback 👍
Comments are sent via email to me.