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.


前言

在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';

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([]); 
  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值