react native netinfo returns true when there is no data connection

110 views Asked by At

I have an issue with the react-native-community/netinfo package

My react-native-community/netinfo version is 9.5.0, and my react native version is 0.70.7.

The react version is 18.1.0

I use isInternetReachable to detect internet reachability and the problem is when I connect with Wi-Fi, but with no data connection the isInternetReachable still returns true. How can I fix it?

I tried every listeners and every possible way that i found in the documentation, but I'm not getting a result.

Can someone help me figure out how to do this?

1

There are 1 answers

8
ko100v.d On

NetInfo streams the updates from the native side directly w/o any computation. This sometimes brings undesired behavior.

https://github.com/react-native-netinfo/react-native-netinfo?tab=readme-ov-file#addeventlistener

Subscribe to connection information. The callback is called with a parameter of type NetInfoState whenever the connection state changes. Your listener will be called with the latest information soon after you subscribe and then with any subsequent changes afterwards. You should not assume that the listener is called in the same way across devices or platforms.

Solution

Netinfo can ping you up to 5+ times whenever the network state is changed, what works for me is to debounce the event listener response for a second, this way it is working as expected. Also, the library doesn't work with iOS Simulator well, you need to test it on a real device.

import { debounce } from 'lodash'
const DEBOUNCE_DURATION = 1000
...
React.useEffect(() => {
    const debouncedListener = debounce((response) => {
        console.log('netInfo response': response)
    }, DEBOUNCE_DURATION)
    const unsubscribe = netInfo.addEventListener((response) => {
        debouncedListener(response)
    })

    return () => {
        // cancel the debounced function when unsubscribing
        debouncedListener.cancel()
        // unsubscribe
        unsubscribe()
    }
}, [])

If you want to solve the issue when the network connection is coming from a hotspot.

You need to use not only isConnected flat but also isInternetReachable. If that is not working for you, you can apply a logic where every time netInfo returns isConnected && isInternetReachable true, you can integrate https://www.npmjs.com/package/react-native-ping and do a double-check, after your event listener emits

import { debounce } from 'lodash'
const DEBOUNCE_DURATION = 1000
...
React.useEffect(() => {
    const debouncedListener = debounce((response) => {
        console.log('netInfo response': response)
        // assuming that isConnected && isInternetReachable are both true.
        try {
            const ms = await Ping.start('114.114.114.114',{ 
            timeout: 1000 });
            // YOU HAVE INTERNET CONNECTION
        } catch (error) {
            // YOU ARE OFFLINE
        }
    }, DEBOUNCE_DURATION)
    const unsubscribe = netInfo.addEventListener((response) => {
        debouncedListener(response)
    })

    return () => {
        // cancel the debounced function when unsubscribing
        debouncedListener.cancel()
        // unsubscribe
        unsubscribe()
    }
}, [])