在react開(kāi)發(fā)中經(jīng)常會(huì)經(jīng)常會(huì)碰到這種警告:Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
原因呢誰(shuí)都知道在已卸載的組件上執(zhí)行setState搭综,解決方案有很多,在卸載的時(shí)候?qū)λ械牟僮鬟M(jìn)行清除、增加一個(gè)標(biāo)記頁(yè)面卸載的時(shí)候重置這個(gè)標(biāo)記等等服爷。
這些解決方案都能解決這個(gè)問(wèn)題蛾派,但對(duì)于我來(lái)說(shuō)不是最好的解決方案橄登,或者說(shuō)不是我想要的解決方案拍柒,分享一個(gè)我的解決方案,擁抱hooks
import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react';
/**
* useUnmounted
* @returns boolean
* whether the component is unmounted
*/
export function useUnmounted() {
const unmountedRef = useRef(false);
useEffect(() => {
return () => {
unmountedRef.current = true;
};
}, []);
return unmountedRef.current;
}
/**
* @method useAsyncState
* Prevent React state update on an unmounted component.
*/
export function useAsyncState<S>(initialState?: S | (() => S)): [S | undefined, Dispatch<SetStateAction<S>>] {
const unmountedRef = useUnmounted();
const [state, setState] = useState(initialState);
const setAsyncState = useCallback((s) => {
if (unmountedRef) return;
setState(s);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return [state, setAsyncState];
}
使用也很方便
const [state, setState] = useState('test');
//替換為
const [state, setState] = useAsyncState('test');
原理我在這就不多做贅述了循头,就是一個(gè)思路的問(wèn)題
更新于2021-12-30