【问题标题】:Cleaning Function not Working in UseEffect Hook During Component Unmount in React Native在 React Native 中卸载组件期间,清理功能在 UseEffect Hook 中不起作用
【发布时间】:2021-07-05 11:34:57
【问题描述】:

在 React Native 应用程序中,App.js 中有两个组件 AB,它们随着 k 状态变化而切换。

App.js

...

const App = () => {
      const [ k, setK ] = useState(false);

      const toggleK = () => setK(!k);

      if(k) {
            return <A />;
      }else {
            return <B toggleK={toggleK} />;
      }
};
...

A 中,setIntervaluseffect 中初始化。它每 10 秒调用一次异步函数。但是当它在App.js 中的K 状态更改上卸载时,清理功能不会运行(没有记录A unmounting...),clearInterval 也是如此。

我在这里做错了什么?

...

const A = () => {
      const [ someState, setSomeState ] = useState(...);

      let timer;

      useEffect(() => {
            if(!timer) {
                  timer = setInterval(async () => await run_async_func(), 10000);
            }

            return () => {
                  console.log('A unmounting...');
                  clearInterval(timer);
            };
      }, [ someState ]);
};
...

【问题讨论】:

  • useState(...)A 里面有什么?您在依赖数组中传递 someState,这意味着 A unomounting... 不会运行,除非 someState 发生变化。
  • @TayyabMazhar 哦,开枪。是的,忽略了!现在可以了。
  • @Waleed93 如果 useEffect 的第一部分调用为什么不调用第二部分(我的意思是如果 setInterval 部分调用为什么不 clearInterval)?

标签: javascript reactjs react-native react-hooks


【解决方案1】:

用 useRef() 试试这个。

const A = () => {
 const timer = useRef()
  const [ someState, setSomeState ] = useState(...);


  useEffect(() => {
        if(!timer) {
              timer.current = setInterval(async () => await run_async_func(), 10000);
        }

        return () => {
              console.log('A unmounting...');
              clearInterval(timer.current);
        };
  }, [ someState ]);
};

【讨论】:

  • 使用useRef 与我所做的没有什么不同。这不仅仅是关于clearInterval,上面的行也没有运行。基本上,尽管k 状态更改为false 并渲染组件B,但卸载组件A 期间的清理操作仍不起作用。
  • 那你能不能创建一个codesandbox链接。另外我认为它应该可以工作我在我的许多项目中都在做完全相同的事情并且它正在工作。此外,您在组件内声明了一个变量,因此在每次渲染时都会再次声明该变量,这就是使用 useref 的原因,所以我真的建议您尝试一次,如果它不起作用,然后请创建一个代码框让我玩
【解决方案2】:

已解决问题

  • 是什么导致了这个问题?

A.忽略了 useEffect 依赖数组中的 someState。基本上,仅当依赖数组中的任何变量发生突变时,清洁函数才会运行。所以,我使用了另一个useEffect,没有任何依赖(见下文)。感谢@TayyabMazhar 指出这一点

...
const A = () => {
      const [ someState, setSomeState ] = useState(...);

      let timer;

      useEffect(() => {
            if(!timer) {
                  timer = setInterval(async () => await run_async_func(), 10000);
            }
      }, [ someState ]);

      useEffect(() => {
            return () => {
                 console.log('A unmounting...');
                 clearInterval(timer);
            };
      }, []);
};
...

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 2020-08-09
    • 1970-01-01
    • 2022-10-15
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多