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(...)
......
}
}, []);