Skip to content

lxsmnsyc/use-dispose

Repository files navigation

use-dispose

React hook for running dispose logic for cancelled components.

NPM JavaScript Style Guide

Usage

Install

yarn add use-dispose

Why?

In Strict mode and Concurrent mode, components may render twice before commit to catch and prevent render-time side-effects. However, since the side-effects scheduled for useLayoutEffect and useEffect are never called on the first render, there could be unintended leaks like double event registrations from external sources.

useDispose attempts to solve this issue by running a registered cleanup for cancelled components, this helps clean and manage leaks that happened on the render phases. useDispose only runs for cancelled components and not for components that runs their side-effects successfully.

import { useDispose } from 'use-dispose';

// Creates an object with a cleanup logic inside it.
// React may create two instances during Strict and Concurrent Mode
// which can lead to undisposed instances like subscriptions.
const [state] = useState(() => new DisposableObject());

// useDispose guarantees that the object gets disposed when
// the component is cancelled.
useDispose(() => {
  state.dispose();
});

// If you want to run disposal only on initial render phase
// You may add "true" as a second argument which toggles
// initial render only cleanup.
useDispose(() => {
  state.dispose();
}, true);

There's also the useDisposableMemo where the produced object from the memoization process which automatically gets disposed when a new object is produced, the component is cancelled or when the component unmounts:

import { useDisposableMemo } from 'use-dispose';

// Create a disposable object that is automatically disposed
// on recomputation and on component cancellation/unmount.
const disposableObject = useDisposableMemo(
  () => new DisposableObject(deps1, deps2),
  (object) => object.dispose(),
  [deps1, deps2],
);

Dispose timeouts

useDispose and useDisposableMemo schedules the dispose callback 5 seconds after the render method is run. You may change this through setDisposeTimeout.

License

MIT © lxsmnsyc