在react开发中会遇到这样的警告: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.
这是由于在已卸载的组件上执行setState造成的(比如:切换路由时)。以下是我列出的一些解决方案。
在卸载的时候对所有的操作执行清除。
class组件(示例):
componentDidMount = () => {
// ajax请求
$.ajax('请求',{})
.then(res => {
this.setState({
aa:true
})
})
.catch(err => {})
}
componentWillUnMount = () => {
// 清除请求
$.ajax.abort()
}
设置一个flag,当卸载的时候重置这个flag。
class组件(示例):
componentDidMount = () => {
this._isMounted = true;
$.ajax('请求',{})
.then(res => {
if(this._isMounted){
this.setState({
aa:true
})
}
})
.catch(err => {})
}
componentWillUnMount = () => {
this._isMounted = false;
}
function组件(示例):
const [isMounted,setIsMounted] = useState(true)
useEffect(() => {
// request请求
queryOverview().then((res) => {
if(isMounted){
setSingle(res.data.single);
}
});
return () => setIsMounted(false);
}, []);
代码如下(示例):
componentDidMount = () => {
$.ajax('请求',{})
.then(res => {
this.setState({
data: datas,
});
})
.catch(error => {});
}
componentWillUnmount = () => {
this.setState = (state,callback)=>{
return;
};
}
自定义Hook 代码如下(示例):
import { useCallback, useEffect, useRef, useState } from 'react';
function useFetchState(...props) {
const focus = useRef();
const [state, setState] = useState(...props);
useEffect(() => {
focus.current = true;
return () => (focus.current = false);
}, []);
const setFetchState = useCallback((...params) => {
focus.current && setState(...params);
}, []);
return [state, setFetchState];
}
export default useFetchState;
使用(将 useState 替换为 useFetchState):
import useFetchState from '@/components/useFetchState';
// 将 useState 替换为 useFetchState
const [total, setTotal] = useFetchState([]);