react-native-netinfo icon indicating copy to clipboard operation
react-native-netinfo copied to clipboard

Implementation of NativeModule.web.ts might be flawed, due to connection events not being synced with online event.

Open Njaah-0 opened this issue 10 months ago • 0 comments

Recently I have spent quite many hours in order to understand odd behavior of this package in web environment (v. 11.4.1). Application where this package is used shows an alert box if user is offline. In my tests if I disable WiFi and then re-enable it, it occasionally would not trigger state change event were isConnected is true. Connection change event WAS triggered, but isConnected was always false. This meant that offline alert did not disappear, even if user was online. Debugging it further, I made a discovery that I believe is a flawed design.

Looking at the getCurrentState function in NativeModule.web.ts, we can see that isConnected is first checked from navigator.onLine: const isConnected = isWindowPresent ? navigator.onLine : false;

Then later on network type is checked based on window.navigator.connection, like this:

const type: NetInfoStateType = connection.type
   ? typeMapping[connection.type]
   : isConnected
   ? NetInfoStateType.other
   : NetInfoStateType.unknown;

Because (window.navigator.)connection.type only truly exists on ChromeOS, this almost always resorts to check that isConnected. If not connected, type is set to NetInfoStateType.unknown. This type uses isConnected prop from navigator.onLine again, to determine the state of isConnected.

This flow itself has nothing wrong itself, but it fails miserably in one particular condition: what if the connection change event from navigator.connection is triggered BEFORE the Window: online event? In such case the navigator.onLine is false, which results to isConnected being false, which then again means that InternetReachability test is never executed!

How can that happen? Well, this is just a theory, but it seems to happen in cases when WiFi is connected pretty quickly, but it takes time before it actually starts working. I can repeat this in approx. 20% of the times I toggle wifi on & off & waiting a little bit between. This behaviour might very well be device specific (based on WiFi adapter) too. I tested this by manually adding listener for Window: online event and inside connection change event.

In any case, core issue lies in the fact that logic relies on connection change event, but then heavily resorts to window.onLine prop, which controlled by a different flow. Best route forward is in my opinion to always listen for Window: online events, not only when navigator.connection is not available. What do you think?

Njaah-0 avatar Mar 14 '25 20:03 Njaah-0