Skip to main content

Lifecycle Hooks Deep Dive

Archibald provides several utility hooks to simplify common React lifecycle patterns and state tracking.


useDidMount

A semantic shortcut for useEffect(callback, []). It ensures the callback runs exactly once after the initial component mount.

useDidMount(() => {
console.log('Component has mounted!');
});

useWillMount

Executes a callback before the initial render. This hook is useful for setup logic that needs to happen before the DOM is created.

useWillMount(() => {
console.log('Component is about to mount!');
});

useIsMounted

Returns a stable MutableRefObject<boolean> that tracks whether the component is currently mounted in the DOM.

  • Best Practice: Use this inside asynchronous operations (like setTimeout or Promise) to avoid updating state on an unmounted component.
const isMounted = useIsMounted();

const handleAsyncAction = async () => {
await someWork();
if (isMounted.current) {
setData(result);
}
};

useIsFirstRender

Returns a boolean that is true only during the very first render of the component.

const isFirst = useIsFirstRender();

if (isFirst) {
console.log('This is the initial render pass.');
}

useDeferredComponent

Dynamically imports a component and renders it only after the host has mounted on the client. Returns null on the server and the first client render (matching SSR — no hydration mismatch), then the loaded component once its import() resolves. The dynamic import is code-split by the bundler and only invoked post-hydration, so the component's code never ships in the initial/critical payload.

function Analytics() {
const Impl = useDeferredComponent(() => import('./AnalyticsImpl'));
return Impl ? <Impl /> : null;
}

Use it for no-UI client trackers or below-the-fold widgets that must stay out of the initial bundle. Unlike React.lazy + Suspense (which resolves during SSR/hydration and needs a boundary), the component here loads strictly after mount. The factory runs once on mount; a cleanup guard prevents a state update if the host unmounts before the import resolves.


How they work Step-by-Step

Scenario: useWillMount vs useDidMount

  1. Rendering Begins: React starts the initial render pass.
  2. useWillMount check: The hook checks its internal useRef. If it's the first run, it immediately executes the callback before anything is rendered.
  3. Component Renders: The JSX is evaluated and the component is added to the DOM.
  4. useDidMount (and useEffect) Execution: After the DOM is updated, React runs the useEffect cleanup/setup cycle.
  5. Status Update: useWillMount updates its ref to false via an internal useDidMount call, ensuring it doesn't run again.

Scenario: useIsMounted Tracking

  1. Hook Initialization: Returns a ref object initialized to false.
  2. Mounting: The component is added to the DOM. The useEffect inside the hook runs, setting ref.current = true.
  3. Unmounting: The component is removed from the DOM. The cleanup function returned by the useEffect runs, setting ref.current = false.

Best Practice: While these hooks provide convenience, always prioritize standard React hooks (useEffect, useMemo) for core logic unless you specifically need the semantic clarity or specialized tracking these utilities provide.