Reputation: 771
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.
Upvotes: 75
Views: 176333
Reputation: 563
For new React you can use
import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import NetInfo from '@react-native-community/netinfo';
const App = () => {
const [isConnected, setIsConnected] = useState(false);
useEffect(() => {
const unsubscribe = NetInfo.addEventListener(state => {
setIsConnected(state.isConnected);
});
// Check initial connection status
NetInfo.fetch().then(state => {
setIsConnected(state.isConnected);
});
// Cleanup subscription on unmount
return () => unsubscribe();
}, []);
return (
<View style={styles.container}>
<Text style={styles.text}>
{isConnected ? 'You are connected to the internet' : 'No internet connection'}
</Text>
<Button title="Check Connection" onPress={() => {
NetInfo.fetch().then(state => {
setIsConnected(state.isConnected);
});
}} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 16,
marginBottom: 20,
},
});
export default App;
Upvotes: 0
Reputation: 31
import React, { useEffect } from 'react';
import { Alert, Platform } from 'react-native';
import PushNotification from 'react-native-push-notification';
import NetInfo from '@react-native-community/netinfo';
const App = () => {
useEffect(() => {
// Configure push notifications
PushNotification.configure({
onRegister: function (token) {
console.log("TOKEN:", token);
},
onNotification: function (notification) {
console.log("NOTIFICATION:", notification);
// Process the notification here
},
requestPermissions: Platform.OS === 'ios'
});
// Check network connectivity
NetInfo.fetch().then(state => {
if (!state.isConnected) {
Alert.alert(
'No Internet Connection',
'Please connect to the internet to receive notifications.',
[{ text: 'OK' }]
);
}
});
// Optionally, you can add a listener to continuously check for network status
const unsubscribe = NetInfo.addEventListener(state => {
if (!state.isConnected) {
Alert.alert(
'No Internet Connection',
'Please connect to the internet to receive notifications.',
[{ text: 'OK' }]
);
}
});
return () => {
unsubscribe(); // Clean up the event listener on unmount
};
}, []);
return (
// Your app's main component
);
};
export default App;
Upvotes: 0
Reputation: 138
Install the expo-network library
$ npx expo install expo-network
Add the library as follows and make the appropriate check
import * as Network from 'expo-network';
...
const netStatus = await Network.getNetworkStateAsync();
if (!netStatus.isConnected) {
// do something here
}
More information can be found in the documentation of Expo here
Upvotes: 4
Reputation: 1006
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>
}
Check Internet connectivity online offline
Upvotes: 0
Reputation: 61
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>
}
Upvotes: 4
Reputation: 10512
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!
Upvotes: 3
Reputation: 167
import NetInfo from "@react-native-community/netinfo";
useEffect(() => {
const removeNetInfoSubscription = NetInfo.addEventListener((state)={
const offline = !(state.isConnected && state.isInternetReachable);
console.log(offline);
});
return () => removeNetInfoSubscription();
}, []);
Upvotes: 1
Reputation: 1334
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!
}
Upvotes: 3
Reputation: 611
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;
Upvotes: 2
Reputation: 790
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>
);
};
Upvotes: 66
Reputation: 314
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/
Upvotes: 1
Reputation: 1607
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();
Upvotes: 24
Reputation: 6683
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()
Upvotes: 8
Reputation: 253
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
Upvotes: 0
Reputation: 502
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
Upvotes: 9
Reputation: 588
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
Upvotes: 8
Reputation: 1220
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>
);
}
}
Upvotes: 30