簡體   English   中英

在 React Native 中卸載組件期間,清理功能在 UseEffect Hook 中不起作用

[英]Cleaning Function not Working in UseEffect Hook During Component Unmount in React Native

App.js 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} />;
      }
};
...

AsetIntervaluseffect初始化。 它每 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 ]);
};
...

用 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 ]);
};

解決了問題

  • 是什么導致了這個問題?

A.忽略了someStateuseEffect依賴性陣列。 基本上,只有在依賴數組中的任何變量發生變異時,更清潔的函數才會運行。 所以,我使用了另一個沒有任何依賴關系的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);
            };
      }, []);
};
...

你可以使用這個鈎子我創造了這個

    import { useEffect, useRef } from 'react';

export const useInterval = (callback: () => void, delay: number): void => {
    const savedCallback = useRef(null);

    // Remember the latest callback.
    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);

    // Set up the interval.
    useEffect(() => {
        function tick() {
            savedCallback.current();
        }
        if (delay !== null) {
            const id = setInterval(tick, delay);
            return () => clearInterval(id);
        }
    }, [delay]);
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM