Home > Blockchain >  Use Effect Cleanup issue
Use Effect Cleanup issue

Time:11-24

The following code is used as an offline monitor within a RN app - its basically used to display a warning if connection drops.

  export default function InternetCheck() {
  const [isConnected, setIsConnected] = useState(false);
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    //Intial status

    NetInfo.fetch().then(state => {
      if (state.isInternetReachable == false) {
        setIsConnected(state.isInternetReachable);
      }
    });
    //Internet connection listener
    NetInfo.addEventListener(state => {
      setIsConnected(state.isInternetReachable);
    });
  }, []);

I am receiving the following error in the console -

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.

Can anyone please explain how to apply a cleanup function in this scenario please? I have read through various other questions but cant get my head around the logic approach.

CodePudding user response:

You can use a mutable boolean variable to track whether cleanup has started for your render cycle. If it has, then bail on updating the (no-longer existing state). Also, be sure to cleanup the NetInfo subscription. Here's an example:

export default function InternetCheck () {
  const [isConnected, setIsConnected] = useState(false);
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    let cleanupStarted = false;

    // Initial status

    NetInfo.fetch().then(state => {
      if (state.isInternetReachable == false) {
        if (!cleanupStarted) setIsConnected(state.isInternetReachable);
      }
    });

    // Internet connection listener
    const unsubscribe = NetInfo.addEventListener(state => {
      if (!cleanupStarted) setIsConnected(state.isInternetReachable);
    });

    return () => {
      cleanupStarted = true;
      unsubscribe();
    };
  }, []);
}

CodePudding user response:

Hello you need to add return callback cleanup from your useEffect function
Like This:

     export default function InternetCheck() {
      const [isConnected, setIsConnected] = useState(false);
      const [mounted, setMounted] = useState(false);
    
      useEffect(() => {
        //Intial status
    
        NetInfo.fetch().then(state => {
          if (state.isInternetReachable == false) {
            setIsConnected(state.isInternetReachable);
          }
        });
        //Internet connection listener
        NetInfo.addEventListener(state => {
          setIsConnected(state.isInternetReachable);
        });
//----> add the removeEventListener 
return ()=>{
NetInfo.removeEventListener(...)
......
}
 }, []);
  • Related