64

I have a React Native application and I'm seeking to add functionality that checks if there is an active internet connection when the app first starts up, and continuously thereafter.

If there is no internet connection, I'm seeking to display a message saying "Internet connection not detected" with a button to "Try again"; if there is an internet connection, I'm seeking to load a page (WebView).

I'm also seeking to support both iOS and Android devices; I've researched this independently and have found a couple libraries on GitHub. However, many require an extra step of including a permissions addition in Android Manifest XML, however I don't see an Android Manifest XML file in my app; why does only Android need a manifest?

Any help is appreciated; thanks and take care.

zstardust225
  • 661
  • 1
  • 5
  • 5
  • 1
    Seems to me that the correct and simple way to get updated about changes is described in https://github.com/react-native-community/react-native-netinfo#usage. Also look at https://github.com/react-native-community/react-native-netinfo#netinfostate for further info, like the difference between isConnected and isInternetReachable – Yossi Aug 29 '20 at 19:50

14 Answers14

55

I ran into this today and found solution which I believe is the best. Its gonna continuously search for network changes and display them accordingly.

I tested it with expo install @react-native-community/netinfo and its working flawlessly.

import {useNetInfo} from "@react-native-community/netinfo";
import {View, Text} from "react-native";
const YourComponent = () => {
  const netInfo = useNetInfo();

  return (
    <View>
      <Text>Type: {netInfo.type}</Text>
      <Text>Is Connected? {netInfo.isConnected.toString()}</Text>
    </View>
  );
};
Lukáš Brýla
  • 680
  • 6
  • 6
  • It has one flaw when I use it. It returns 'null' first, then, returns 'true' or 'false'. That 'null' is annoying. – Four Apr 17 '22 at 16:30
  • If the connections changes later it doesn't update. How can we update it if the connection changes? – gggx Apr 22 '22 at 09:39
  • 2
    `useNetInfo` is a react hook, which will auto update component state if the connection state changes. Make sure you're following the example, or take a time to learn react hooks/components/etc – Jone Polvora Jun 15 '22 at 18:12
28

Please read this https://reactnativeforyou.com/how-to-check-internet-connectivity-in-react-native-android-and-ios/ link.

import React, { Component } from "react";
import { View, Text, Button, Alert, NetInfo, Platform } from "react-native";

export default class componentName extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  CheckConnectivity = () => {
    // For Android devices
    if (Platform.OS === "android") {
      NetInfo.isConnected.fetch().then(isConnected => {
        if (isConnected) {
          Alert.alert("You are online!");
        } else {
          Alert.alert("You are offline!");
        }
      });
    } else {
      // For iOS devices
      NetInfo.isConnected.addEventListener(
        "connectionChange",
        this.handleFirstConnectivityChange
      );
    }
  };

  handleFirstConnectivityChange = isConnected => {
    NetInfo.isConnected.removeEventListener(
      "connectionChange",
      this.handleFirstConnectivityChange
    );

    if (isConnected === false) {
      Alert.alert("You are offline!");
    } else {
      Alert.alert("You are online!");
    }
  };

  render() {
    return (
      <View>
        <Button
          onPress={() => this.CheckConnectivity()}
          title="Check Internet Connectivity"
          color="#841584"
          accessibilityLabel="Learn more about this purple button"
        />
      </View>
    );
  }
}
Mirzohid Akbarov
  • 1,192
  • 1
  • 10
  • 17
  • 2
    This is helpful; however, how do you persistently check internet connection without the button (if an internet connection state changes, then trigger action)? – zstardust225 Jul 31 '19 at 19:05
  • That is callback for connection change `NetInfo.isConnected.addEventListener( "connectionChange", this.handleFirstConnectivityChange );` `handleFirstConnectivityChange = isConnected => { //NetInfo.isConnected.removeEventListener("connectionChange",this.handleFirstConnectivityChange); if (isConnected === false) { Alert.alert("You are offline!"); } else { Alert.alert("You are online!"); } };` – Mirzohid Akbarov Jul 31 '19 at 19:15
  • Okay; however, where does that code go (is it within the handleFirstConnectivityChange method?) – zstardust225 Jul 31 '19 at 19:24
  • whenhandleFirstConnectivityChange() methode called when connection change – Mirzohid Akbarov Jul 31 '19 at 19:31
  • It's not working on change automatically (no button press); I added it to the handleFirstConnectivityChange() method... – zstardust225 Jul 31 '19 at 19:44
  • I don't understand why the code needs to be different between iOS and android. Seems to me that the correct and simple way to get updated about changes is described in https://github.com/react-native-community/react-native-netinfo#usage. Also look at https://github.com/react-native-community/react-native-netinfo#netinfostate for further info, like the difference between isConnected and isInternetReachable – Yossi Aug 29 '20 at 19:49
  • 11
    NetInfo is No longer part of the react-native project. It got separated out of the core. You can use this example -> https://stackoverflow.com/a/64295620/1953383 – twboc Oct 10 '20 at 16:20
22

It seems this question is all over stackoverflow and no one seems to look at other existing answers.

You should use the "@react-native-community/netinfo" library. NetInfo used to be part of the react-native, but then it got separated out of the core. If you want to observe network state changes just use the provided addEventListener method.

import NetInfo from "@react-native-community/netinfo";

NetInfo.fetch().then(state => {
    console.log("Connection type", state.type);
    console.log("Is connected?", state.isConnected);
});

const unsubscribe = NetInfo.addEventListener(state => {
    console.log("Connection type", state.type);
    console.log("Is connected?", state.isConnected);
});

// Unsubscribe
unsubscribe();
twboc
  • 1,452
  • 13
  • 17
  • I'm having problem when toggling wifi on/off or switching between wifi and cellular in Android though. The state values are not updated. – Jeaf Gilbert Dec 27 '21 at 04:30
  • @JeafGilbert Do you do that in background or foreground? Maybe you could paste the code? I assume when you open the options the app goes into the background and that would require a different listener in a background task. This could also be connected to hibernation issues. https://github.com/react-native-netinfo/react-native-netinfo/issues/537 – twboc Dec 27 '21 at 15:19
  • 1
    Turns out that updating from v6.0.0 to v.7.1.7 caused this. So I rolled it back to v6.0.0 and working again. – Jeaf Gilbert Dec 27 '21 at 15:20
  • Where should the code sample be saved? – Green May 25 '23 at 02:43
  • 1
    Create a folder for network code or modules that your app uses. And then call the methods provided here in some init block code of your app. And unsubscribe when you close the app. – twboc May 25 '23 at 12:48
9

NetInfo has been removed from React-Native. It can now be installed and imported from 'react-native-netinfo' instead from 'react-native'. See https://github.com/react-native-community/react-native-netinfo

Jocelyn Nsa
  • 474
  • 6
  • 10
8

For it react-native provide a library called netinfo: please check on: https://github.com/react-native-community/react-native-netinfo

It provides an api to check the connectivity and its type.

NB: if you are using RN < 0.60: https://facebook.github.io/react-native/docs/netinfo.html

Steve Alves
  • 598
  • 5
  • 12
6

Create NetworkUtills.js

import NetInfo from "@react-native-community/netinfo";
export default class NetworkUtils {
  static async isNetworkAvailable() {
    const response = await NetInfo.fetch();
    return response.isConnected;
}}

Use anywhere like this

const isConnected = await NetworkUtils.isNetworkAvailable()
Rajesh N
  • 6,198
  • 2
  • 47
  • 58
3

Here is an up-to-date solution on how to check if your app can reach the internet.

Start by installing the official NetInfo community package:

yarn add @react-native-community/netinfo

Then the snippet.

import { Platform } from "react-native";
import NetInfo from "@react-native-community/netinfo";
...


const checkConnectivity: Promise<boolean | null> = () => {
    return new Promise(resolve => {
        if (Platform.OS === "android") {
            // For Android devices
            NetInfo.fetch().then(state => {
                resolve(state.isInternetReachable);
            });
        } else {
            // For iOS devices
            const unsubscribe = NetInfo.addEventListener(state => {
                unsubscribe();
                resolve(state.isInternetReachable);
            });
        }
    });
};

...

And it's usage

...
const hasInternetAccess = await checkConnectivity();

if(hasInternetAccess) {
   // My app can reach the internet
} 
else {
  // Can't connect to the internet. Too bad!
}

Cels
  • 1,212
  • 18
  • 25
  • how unsubscribe() function works defined inside NetInfo.addEventListener ? getting error - undefined unsubscribe() – Rahul.S Mar 20 '22 at 23:05
  • @Rahul.S, calling `NetInfo.addEventListener` will return a callback that can be used to unsubscribe from the event listener. You can have a look at some examples on the npm page for the package here https://www.npmjs.com/package/@react-native-community/netinfo – Cels Mar 25 '22 at 09:17
3

Lots of credits to the answers here, but here's a complete example with the useNetInfo React Hook triggering when the state will change, Alert to inform the user, and displaying View with some text to the user.

import { useNetInfo, NetInfoState } from "@react-native-community/netinfo";
import {
  Alert,
  StyleSheet,
  Text,
  View,
} from "react-native";
...
const internetState: NetInfoState = useNetInfo();
...
useEffect(() => {
  if (internetState.isConnected === false) {
    Alert.alert(
      "No Internet! ❌",
      "Sorry, we need an Internet connection for MY_APP to run correctly.",
      [{ text: "Okay" }]
    );
  }
}, [internetState.isConnected]);
...
if (internetState.isConnected === false) {
  return (
    <View style={styles.centered}>
      <Text style={styles.title}>
        Please turn on the Internet to use MY_APP.
      </Text>
    </View>
  );
}
...
const styles = StyleSheet.create({
  centered: {
    alignItems: "center",
    flex: 1,
    justifyContent: "center",
  },
  title: {
    fontSize: 20,
    fontWeight: "bold",
    textAlign: "center",
  },
});

PS. I couldn't succeed to include it in App.tsx or navigation/index.tsx to avoid code duplication. Next try, I've included the logic in every screen. For the App.tsx or navigation/index.tsx case, whenever internet was back, the user was redirected to the starting screen of the app, which is not what I wanted. I wanted, when the internet is back, to be back on the screen where the user ended. With the logic in multiple screens, multiple alerts are being fired :( Finally, I've included the Alert-related logic in App.tsx, whereas the View with information about no internet in each screen. The Alert pops up only once, but it'd be the best to avoid code duplication, too, regarding the View. Please feel free to post an update, if you know how to do it from 1 location of the codebase in the application. It'd be so much appreciated!

Daniel Danielecki
  • 8,508
  • 6
  • 68
  • 94
2

I'm using react-native 0.66.3 I have added this code to Splash screen, so when NetInfo returns "isConnected : false", then I Show the Try Again button for check network if network is connected, navigation replaced to home screen.

this is my splash screen:

import React, { useEffect, useState } from "react";
...
import NetInfo from "@react-native-community/netinfo";

const Splash = (props) => {
  const [network, setNetwork] = useState('')
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    unsubscribe()
  }, []);

  function unsubscribe() {
    NetInfo.fetch().then(state => {
      setNetwork(state)
      setTimeout(function () {
        if (state.isConnected) {
          // any thing you want to load before navigate home screen
        } else {
          setLoading(false)
        }
      }, 500);
    })
  };



  return (
    <View style={{
      flex: 1,
      backgroundColor: global.bgBody,
      justifyContent: 'center',
      alignItems: 'center'
    }}>
      <Image
        source={Logo}
        style={{
          width: 150,
          height: 123,
        }}
      />
      {!network?.isConnected || loading ? <View style={{ marginTop: 30 }}>
        <Description text={`Please check your internet connection and try again`} />
        <Button
          title="Try Again"
          onPress={() => {
            setLoading(true)
            unsubscribe()
          }}
          loading={loading}
        />
      </View> : null}
    </View>
  );
};
export default Splash;
fatemeh kazemi
  • 516
  • 6
  • 10
2

This is what worked for me (using TypeScript)

import React, {useEffect, useState} from "react";
import NetInfo, {NetInfoState} from "@react-native-community/netinfo";

const OfflineScreen = () => {
    const [isOffline, setIsOffline] = useState(false);
    useEffect(() => {
        const removeNetInfoSubscription = NetInfo.addEventListener((state: NetInfoState) => {
          const offline = !(state.isConnected && state.isInternetReachable)
          console.log(offline)
          setIsOffline(offline)
        })
    
        return () => removeNetInfoSubscription()
      }, [])

    return <Text>{`Internet Status: ${isOffline}`}</Text>
}
KhetheloGP
  • 31
  • 3
  • This answer should be the checked one. Because it uses an event listener and it would be updated if `refresh` method is used. – Ali Bahaari Aug 17 '23 at 00:45
1

For expo:

import NetInfo from "@react-native-community/netinfo";

export const checkConnected = () => {
  return NetInfo.fetch().then((state) => {
    console.log("Connection type", state.type);
    console.log("Is connected?", state.isConnected);
    return state.isConnected;
  });
};

Check out this documentaion: https://docs.expo.dev/versions/latest/sdk/netinfo/

Arnav Singh
  • 194
  • 2
  • 4
1
import NetInfo from "@react-native-community/netinfo";

useEffect(() => {
const removeNetInfoSubscription = NetInfo.addEventListener((state)={

const offline = !(state.isConnected && state.isInternetReachable);

console.log(offline);

});

return () => removeNetInfoSubscription();
}, []);
Thaiyalnayaki
  • 148
  • 1
  • 8
0

The Android manifest file is here: \android\app\src\main\AndroidManifest.xml. Further use this library to do your require https://github.com/react-native-community/react-native-netinfo

Tung Nguyen
  • 223
  • 3
  • 10
0
import {useNetInfo} from "@react-native-community/netinfo";

 const netInfo = useNetInfo();

  const [visible, setVisible] = useState(true)

  useEffect(() => {
    setVisible(!netInfo?.isConnected )
  }, [])
  

  useEffect(() => {
    setVisible(true)

    setTimeout(() => {
      if(netInfo?.isConnected ){
        setVisible(false)
      }
    }, 2000);

  }, [netInfo?.isConnected])

 {visible &&
      <Text style={{ marginTop:20,
              backgroundColor:netInfo?.isConnected ? "green":'red',
              paddingVertical:30, textAlign:'center',
              fontWeight:'bold', fontSize:18}}>
             {netInfo?.isConnected? "back online" : "Could not connect to the internet..." }
      </Text>
      }

enter image description here

enter image description here Check Internet connectivity online offline

Sourabh Gera
  • 862
  • 7
  • 7