use-is-mounted-ref
v2.1.1
Published
📦 React Hooks for mount state tracking and auto-cleanup with AbortController.
Downloads
661,669
Maintainers
Readme
Table of Contents
Motivation
Prevent memory leaks and auto-cancel async work when components unmount. React Strict Mode compatible.
Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.Installation
yarn add use-is-mounted-ref
# or
npm install use-is-mounted-refHooks
useIsMountedRef
Track component mount state with a ref.
import { useState, useEffect } from 'react';
import { useIsMountedRef } from 'use-is-mounted-ref';
function App() {
const isMountedRef = useIsMountedRef();
const [state, setState] = useState({
loading: true,
error: false,
data: [],
});
useEffect(() => {
fetch('https://api.example.com/data')
.then((response) => response.json())
.then(({ data }) => {
if (isMountedRef.current) {
setState((prev) => ({ ...prev, loading: false, data }));
}
})
.catch((err) => {
if (isMountedRef.current) {
setState((prev) => ({ ...prev, loading: false, error: true }));
}
});
}, [isMountedRef]);
return state.loading ? 'Loading...' : 'Found Data!';
}useAbortController
Automatically abort fetch requests and async operations on unmount.
import { useState, useEffect } from 'react';
import { useAbortController } from 'use-is-mounted-ref';
function App() {
const abortController = useAbortController();
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data', {
signal: abortController.signal,
})
.then((response) => response.json())
.then(setData)
.catch((err) => {
if (err.name !== 'AbortError') {
console.error(err);
}
});
}, [abortController]);
return <div>{data ? 'Loaded!' : 'Loading...'}</div>;
}useAbortSignal
Returns an AbortSignal that automatically aborts on unmount. Simpler API for the most common use case — you usually only need the signal, not the full controller.
import { useState, useEffect } from 'react';
import { useAbortSignal } from 'use-is-mounted-ref';
function UserProfile({ id }) {
const signal = useAbortSignal();
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${id}`, { signal })
.then((res) => res.json())
.then(setUser)
.catch((err) => {
if (err.name !== 'AbortError') {
console.error(err);
}
});
}, [id, signal]);
return <div>{user?.name}</div>;
}The signal option in addEventListener removes the listener automatically when aborted — no need for manual removeEventListener.
import { useEffect } from 'react';
import { useAbortSignal } from 'use-is-mounted-ref';
function useWindowResize(callback) {
const signal = useAbortSignal();
useEffect(() => {
window.addEventListener('resize', callback, { signal });
}, [callback, signal]);
}import { useEffect } from 'react';
import { useAbortSignal } from 'use-is-mounted-ref';
function useDelayedAction(action, delay) {
const signal = useAbortSignal();
useEffect(() => {
const id = setTimeout(action, delay);
signal.addEventListener('abort', () => clearTimeout(id));
}, [action, delay, signal]);
}import { useState, useEffect } from 'react';
import { useIsMountedRef, useAbortController } from 'use-is-mounted-ref';
function App() {
const isMountedRef = useIsMountedRef();
const abortController = useAbortController();
const [state, setState] = useState({ loading: true, data: null });
useEffect(() => {
fetch('https://api.example.com/data', {
signal: abortController.signal,
})
.then((res) => res.json())
.then((data) => {
if (isMountedRef.current) {
setState({ loading: false, data });
}
})
.catch((err) => {
if (err.name !== 'AbortError' && isMountedRef.current) {
setState({ loading: false, data: null });
}
});
}, [abortController, isMountedRef]);
return state.loading ? 'Loading...' : 'Loaded!';
}Migration from v1 to v2
Breaking change: Default export replaced with named exports.
- import useIsMountedRef from 'use-is-mounted-ref';
+ import { useIsMountedRef } from 'use-is-mounted-ref';New hook available:
import { useAbortController } from 'use-is-mounted-ref';Contributing
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
Bugs and Sugestions
Report bugs or do suggestions using the issues.
