Search code examples
javascriptreactjsreduxreact-redux

Detect network connection in React Redux app - if offline, hide component from user


I am using google's autocomplete API to improve address input in my form.

I am using GoogleMapsLoader loader which dispatches action once loaded:

GoogleMapsLoader.onLoad(function() {
    store.dispatch(GoogleActions.loaded());
});

In React component I have following input:

if (google.status === 'LOADED') {
    inputGoogle = <div>
        <label htmlFor={`${group}.google`}>Auto Complete:</label>
        <input ref={(el) => this.loadAutocomplete(el)} type="text" />
    </div>;
} else {
    inputGoogle = '';
}

the loadAutocomplete method (not sure if it is best way of doing that) :

loadAutocomplete(ref) {
    if (!this.autocomplete) {
        this.search = ref;
        this.autocomplete = new google.maps.places.Autocomplete(ref);
        this.autocomplete.addListener('place_changed', this.onSelected);
    }
},

UPDATE:

Using answer below I did following:

const GoogleReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'GOOGLE_LOADED':
            return Object.assign({}, state, {
                status: 'LOADED',
                connection: 'ONLINE'
            });
        case 'GOOGLE_OFFLINE':
            return Object.assign({}, state, {
                connection: 'OFFLINE'
            });
        case 'GOOGLE_ONLINE':
            return Object.assign({}, state, {
                connection: 'ONLINE'
            });
        default:
            return state;
    }
};

const GoogleActions = {
    loaded: () => {
        return (dispatch) => {
            dispatch({
                type: 'GOOGLE_LOADED',
            });
        };
    },
    onOnline: () => {
        return (dispatch) => {
            window.addEventListener('online', function() {
                dispatch({
                    type: 'GOOGLE_ONLINE'
                });
            });
        };
    },
    onOffline: () => {
        return (dispatch) => {
            window.addEventListener('offline', function() {
                dispatch({
                    type: 'GOOGLE_OFFLINE'
                });
            });
        };
    }
};

Inside React component:

if (google.status === 'LOADED' && google.connection === 'ONLINE') {
    inputGoogle = <div>
        <label htmlFor={`${group}.google`}>Auto Complete:</label>
        <input ref={(el) => this.loadAutocomplete(el)} name={`${group}.google`} id={`${group}.google`} type="text" onFocus={this.clearSearch}/>
    </div>;
} else {
    inputGoogle = <p>Auto Complete not available</p>;
}

So far works.


Solution

  • you can use the onLine method of the Navigator object, returns a boolean, true if online, then just add a statement in your react render.

    https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine

    render(){
        var input = navigator.onLine ? <YOUR_FORM_COMPONENT> : null;
        return(
        <div>
            {input}
        </div>
        )    
    }