I have a React component, that includes the availability flag of Internet connectivity. UI elements have to be dynamically changed according to state real-time. Also, functions behave differently with the changes of the flag.
My current implementation polls remote API using Axios in every second using interval and updates state accordingly. I am looking for a more granular and efficient way to do this task to remove the 1-second error of state with the minimum computational cost. Considered online if and only if device has an external Internet connection
Current implementation :
class Container extends Component {
constructor(props) {
super(props)
this.state = {
isOnline: false
};
this.webAPI = new WebAPI(); //Axios wrapper
}
componentDidMount() {
setInterval(() => {
this.webAPI.poll(success => this.setState({ isOnline: success });
}, 1000);
}
render() {
return <ChildComponent isOnline={this.state.isOnline} />;
}
}
Edited:
Looking for a solution capable of detecting external Internet connectivity. The device can connect to a LAN which doesn't have an external connection. So, it is considered offline. Considers online if and only if device has access to external Internet resources.
setState() setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses.
There are basically two ways to share state between multiple components: Shift state into a parent component. Store the state externally using React Context or a state framework like Redux.
Offline-first means that you build your React Native app so that it can work with or without an Internet connection.
The “react-detect-offline” package can also be used to display content or style your content based on your network connectivity (connected/disconnected). If an app is likely to be used in poor network areas or while travelling then it’s probably best to go with an “ Offline first ” approach.
An offline first app is an app whose core functionality works even in the absence of a network connection. When we create a react app using create-react-app command (assuming we have all the requirements to run react app on our system), the app will contain a file called “service-worker.js” .
In the component above, we have the handleConnectionChange method that updates the isDisconnected property in our local state as a result of a change in the Javascript “navigator.onLine” property which returns a boolean. This boolean is changed and updated accordingly based on the browser’s ability to fetch any resource on the internet.
You can use https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event
window.addEventListener('offline', (event) => {
console.log("The network connection has been lost.");
});
and https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event for checking when you're back online
window.addEventListener('online', (event) => {
console.log("You are now connected to the network.");
});
Method one: Using legacy browser API - Navigator.onLine
Returns the online status of the browser. The property returns a boolean value, with true meaning online and false meaning offline. The property sends updates whenever the browser's ability to connect to the network changes. The update occurs when the user follows links or when a script requests a remote page. For example, the property should return false when users click links soon after they lose internet connection.
You can add it to your component lifecycle:
Play with the code below using Chrome dev tools - switch "Online" to "Offline" under the Network tab.
class App extends React.PureComponent {
state = { online: window.navigator.onLine }
componentDidMount() {
window.addEventListener('offline', this.handleNetworkChange);
window.addEventListener('online', this.handleNetworkChange);
}
componentWillUnmount() {
window.removeEventListener('offline', this.handleNetworkChange);
window.removeEventListener('online', this.handleNetworkChange);
}
handleNetworkChange = () => {
this.setState({ online: window.navigator.onLine });
}
render() {
return (
<div>
{ this.state.online ? 'you\'re online' : 'you\'re offline' }
</div>
);
}
}
ReactDOM.render(
<App />
, document.querySelector('#app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
However, I think this isn't what you want, you wanted a real-time connection validator.
Method two: Checking internet connection by using it
The only solid confirmation you can get if the external internet connectivity is working is by using it. The question is which server you should call to minimize the cost?
There are many solutions on the internet for this, any endpoint that responds with a quick 204 status is perfect, e.g.:
IMO, if you are running this React app on a server, it makes the most sense to call to your own server, you can call a request to load your /favicon.ico
to check the connection.
This idea (of calling your own server) has been implemented by many libraries, such as Offline
, is-reachable
, and is widely used across the community. You can use them if you don't want to write everything by yourself. (Personally I like the NPM package is-reachable
for being simple.)
Example:
import React from 'react';
import isReachable from 'is-reachable';
const URL = 'google.com:443';
const EVERY_SECOND = 1000;
export default class App extends React.PureComponent {
_isMounted = true;
state = { online: false }
componentDidMount() {
setInterval(async () => {
const online = await isReachable(URL);
if (this._isMounted) {
this.setState({ online });
}
}, EVERY_SECOND);
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
return (
<div>
{ this.state.online ? 'you\'re online' : 'you\'re offline' }
</div>
);
}
}
I believe what you have currently is already fine, just make sure that it is calling the right endpoint.
Similar SO questions:
Setup a hook with the online, offline events. then update a state and return it. This way you can use it anywhere in your app with an import. Make sure you clean up with the return function. If you don't you will add more and more event listeners each time a component using the hook mounts.
const onlineHook = () => {
const {isOnline, setOnline} = React.useState();
React.useEffect(() => {
const goOnline = function(event){
setOnline(true);
});
const goOffline = function(event){
setOnline(false);
});
window.addEventListener('offline', goOffline);
window.addEventListener('online', goOnline);
return () => {
window.removeEventListener('offline', goOffline);
window.removeEventListener('online', goOnline);
}
}, [])
return isOnline
}
To use this just import the above hook and call it like this.
const isOnline = onlineHook(); // true if online, false if not
You can create a component to share between all subcomponents
used:
import React, { useState, useEffect } from "react";
export default function NetworkChecker() {
const [networkStatus, setNetworkStatus] = useState(true)
useEffect(() => {
window.addEventListener('offline', (event) => {
setNetworkStatus(false)
});
window.addEventListener('online', (event) => {
setNetworkStatus(true)
});
return function cleanupListener() {
window.removeEventListener('online', setNetworkStatus(true))
window.removeEventListener('offline', setNetworkStatus(false))
}
},[])
if (networkStatus) {
return <div className={"alert-success"}>Online</div>
} else {
return <div className={"alert-danger"}>Offline</div>
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With