当前位置: 首页 > 工具软件 > AttC > 使用案例 >

React解决Warning: Can‘t perform a React state update on an unmounted component.

荣声
2023-12-01


前言

在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([]); 
 类似资料: