react报错:Warning: Can't perform a React state update on an unmounted component. This is a no-op, but

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.

今天在写react的时候报了如上错误,完整信息如下:

 造成的原因:组件在卸载之后(比如你切换路由卸载一些组件)依然去更新了state。这里可能是setState,当然也可能是在useState里面的setState(一样的)

两种情况:

  1. 设置了定时器setinterval 或者递归setTimeout。 组件在之前没有清除掉。
  2. 异步请求callback在请求回来之前组件已经被卸载掉了

解决办法

1. 对于定时器

componentWillUnmount 生命周期, 必须clear调用定时器

2.对于异步请求

两种解决方案。

  1. 设置标志位在挂载是为true,componentWillUnmount 时设为false,然后在异步调用的callback里面做判断
  2. componentWillUnmount 取消异步请求

这里来一个我自己的栗子,其中使用了定时器和数据请求,当切换路由卸载组件时报了上面的错误:

const [items,setItems] = useState([123,456]);
useEffect(_=>{
        let ignore = false;
        async function fetchData(){
            let res = await post('situationIndex3!getStaffData.action');
            res = res.data;
            if(!ignore) setItems(res);
        }

        (function dataTimeInterval(){
            setTimeout(_=>{
                fetchData();
                dataTimeInterval();
            },1000)
        })()
        
        return _=>{
            ignore = true;
        }
    },[]);

return (...)

这里再useEffect中设置了一个是否不在渲染的flag(ignore)。如果ignore为false,这更新state,如果为true则不再更新state。当组件卸载的时候,将ignore设置为true,即当异步请求回来的时候组件已经卸载了,但是判定为true就不会更新state。

另外注意因为我每隔一秒去请求一次数据,为了避免每次更新都执行effet,这里useEffet的依赖项为[]即选然后只执行一次effect。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值