【问题标题】:Can't perform a React state update on an unmounted component. This is a no-op无法对未安装的组件执行 React 状态更新。这是一个无操作
【发布时间】:2021-10-13 20:48:23
【问题描述】:

这是控制台中的警告,

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

这是我的代码

const [index, setIndex] = useState(0);
  const [refreshing, setRefreshing] = useState(false);
  const refContainer: any = useRef();
  const [selectedIndex, setSelectedIndex] = useState(0);
  const navigation = useNavigation();

  useEffect(() => {
    refContainer.current.scrollToIndex({animated: true, index});
  }, [index]);

  const theNext = (index: number) => {
    if (index < departments.length - 1) {
      setIndex(index + 1);
      setSelectedIndex(index + 1);
    }
  };

  setTimeout(() => {
    theNext(index);
    if (index === departments.length - 1) {
      setIndex(0);
      setSelectedIndex(0);
    }
  }, 4000);

  const onRefresh = () => {
    if (refreshing === false) {
      setRefreshing(true);
      setTimeout(() => {
        setRefreshing(false);
      }, 2000);
    }
  };

我应该怎么做才能清理干净?

我尝试做很多事情,但警告没有消失

【问题讨论】:

    标签: reactjs react-native use-effect use-state


    【解决方案1】:

    setTimeout 需要在useEffect 中使用。并添加明确的超时作为回报

      useEffect(() => {
        const timeOut = setTimeout(() => {
          theNext(index);
          if (index === departments.length - 1) {
            setIndex(0);
            setSelectedIndex(0);
          }
        }, 4000);
    
        return () => {
          if (timeOut) {
            clearTimeout(timeOut);
          }
        };
      }, []);
    

    【讨论】:

    • 警告消失但滑块不起作用,它只会自动滚动1次并停止
    • 哦。你想调用multies。只需删除useEffect 的最后一个[]。它会在每次重新渲染时调用
    【解决方案2】:

    这是一个简单的解决方案。首先,您必须像这样删除所有计时器。

    useEffect(() => {
       return () => remover timers here ;
    },[])
    

    然后放这个

    import React, { useEffect,useRef, useState } from 'react'
    
    const Example = () => {
        const isScreenMounted = useRef(true)
        useEffect(() => {
            isScreenMounted.current = true
            return () =>  isScreenMounted.current = false
        },[])
           
        const somefunction = () => {
            // put this statement before every state update and you will never get that earrning
            if(!isScreenMounted.current) return;
            /// put here state update function
        }
        return null
    }
    
    export default Example; 
    

    【讨论】:

      猜你喜欢
      • 2019-09-26
      • 2021-07-01
      • 2020-11-21
      • 2019-11-09
      • 2019-05-30
      • 2021-05-30
      相关资源
      最近更新 更多