在 React Redux 应用程序中检测网络连接 - 如果离线,对用户隐藏组件

我正在使用谷歌的自动完成 API 来改进表单中的地址输入。

我正在使用 GoogleMapsLoader 加载程序,它在加载后调度操作:

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

在 React 组件中,我有以下输入:

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

loadAutocomplete 方法(不确定它是否是最好的方法):

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

更新:

使用下面的答案我做了以下事情:

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'
                });
            });
        };
    }
};

React 组件内部:

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>;
}

到目前为止有效。

stack overflow Detect network connection in React Redux app - if offline, hide component from user
原文答案
author avatar

接受的答案

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>
    )    
}

答案:

作者头像

I have been using react-detect-offline to handle displaying online/offline specific content, it handles older browsers who do not support the online event with polling and you can specify the polling URL in the options.

https://github.com/chrisbolin/react-detect-offline

First install the package

npm install react-detect-offline

Then in your component you would do something like

import { Offline, Online } from "react-detect-offline"

const MyComponent = () => {
    return (
        <div>
            <Offline>You're offline right now. Check your connection.</Offline>
            <Online>You're online right now.</Online>
        </div>
    );
}
作者头像

navigator.onLine will return the status whether it is online or offline but it wont check internet connectivity is there or not. Adding bit more to @StackOverMySoul. To get rid of this can refer below example.

    var condition = navigator.onLine ? 'online' : 'offline';
    if (condition === 'online') {
      console.log('ONLINE');
        fetch('https://www.google.com/', { // Check for internet connectivity
            mode: 'no-cors',
            })
        .then(() => {
            console.log('CONNECTED TO INTERNET');
        }).catch(() => {
           console.log('INTERNET CONNECTIVITY ISSUE');
        }  )

    }else{
       console.log('OFFLINE')
    }

Why choose google.com?

The reason behind sending the get request to google.com instead of any random platform is because it has great uptime. The idea here is to always send the request to a service that is always online. If you have a server, you could create a dedicated route that can replace the google.com domain but you have to be sure that it has an amazing uptime.

作者头像

Use navigator.onLine to check network connectivity. It return true if network connection is available else return false.

Also try to use navigator.connection to verify network connection status.

var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
    if (connection) {
      if (connection.effectiveType === 'slow-2g')
        preloadVideo = false;
    }

For more Network Information API

作者头像

对于 reacttypescript 编码器:这家伙有简单且可重用的解决方案 https://medium.com/@vivekjoy/usenetwork-create-a-custom-react-hook-to-detect-online-and-offline-network-status-and-get-network-4a2e12c7e58b

对我有用。

作者头像

You can create a custom hook and try to send requests each five seconds:

import { useState, useEffect } from 'react';

const useNetworkStatus = () => {
  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {
    const interval = setInterval(() => {
      fetch('https://www.google.com/', {
        mode: 'no-cors',
      })
        .then(() => !isOnline && setIsOnline(true))
        .catch(() => isOnline && setIsOnline(false));
    }, 5000);

    return () => clearInterval(interval);
  }, [isOnline]);

  return { isOnline };
};

export default useNetworkStatus;

And then use it like this:

import useNetworkStatus from '@/hooks/useNetworkStatus';
// ...
const { isOnline } = useNetworkStatus();