React解决Warning: Can't perform a React state update on an unmounted component.
前言
在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);},[]);
简单方式(class组件)
代码如下(示例):
componentDidMount=()=>{
$.ajax('请求',{}).then(res=>{
this.setState({
data: datas,});}).catch(error=>{});}
componentWillUnmount=()=>{
this.setState=(state,callback)=>{return;};}
React Hook里比较好的方式(自定义Hook)
自定义Hook 代码如下(示例):
import{ useCallback, useEffect, useRef, useState} from'react';
functionuseFetchState(...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];}
exportdefault useFetchState;
使用(将 useState 替换为 useFetchState):
import useFetchState from'@/components/useFetchState';// 将 useState 替换为 useFetchStateconst[total, setTotal]=useFetchState([]);