Динамическое изменение состояния на основе внешнего подключения Inte rnet - React (автономно / онлайн) - PullRequest
9 голосов
/ 31 марта 2020

У меня есть компонент React, который включает флаг доступности подключения Inte rnet. Элементы пользовательского интерфейса должны динамически изменяться в соответствии с состоянием в реальном времени. Кроме того, функции ведут себя по-разному с изменениями флага.

Моя текущая реализация опрашивает удаленный API, используя Ax ios каждую секунду, используя интервал, и соответственно обновляет состояние. Я ищу более детальный и эффективный способ выполнить эту задачу, чтобы устранить 1-секундную ошибку состояния с минимальными вычислительными затратами. Рассматривается онлайн тогда и только тогда, когда устройство имеет внешнее соединение Inte rnet

Текущая реализация:

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

Отредактировано:

Ищите решение, способное обнаруживать внешние соединения Inte rnet. Устройство может подключаться к локальной сети, которая не имеет внешнего подключения. Таким образом, это считается в автономном режиме. Рассматривает онлайн тогда и только тогда, когда устройство имеет доступ к внешним ресурсам Inte rnet.

Ответы [ 4 ]

8 голосов
/ 31 марта 2020

Вы можете использовать https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event

window.addEventListener('offline', (event) => {
    console.log("The network connection has been lost.");
});

и https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event для проверки, когда вы вернетесь в сеть

window.addEventListener('online', (event) => {
    console.log("You are now connected to the network.");
});
2 голосов
/ 24 апреля 2020

Метод первый: использование устаревшего API браузера - Navigator.onLine

Возвращает онлайн-статус браузера. Свойство возвращает логическое значение с истинным значением онлайн и ложным значением автономно. Свойство отправляет обновления всякий раз, когда способность браузера подключаться к сети изменяется. Обновление происходит, когда пользователь переходит по ссылкам или когда скрипт запрашивает удаленную страницу. Например, свойство должно возвращать значение false, если пользователи нажимают на ссылки вскоре после того, как теряют соединение inte rnet.

Вы можете добавить его в жизненный цикл компонента:

Играть с кодом ниже с помощью Chrome dev tools - переключите «Онлайн» на «Автономный» на вкладке «Сеть».

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>

Однако я думаю, что это не то, что вам нужно, вы хотели средство проверки подлинности в реальном времени.

Способ два: проверка соединения inte rnet с помощью него

Единственное подтверждение solid, которое вы можете получить, если работает внешнее соединение inte rnet, - используя Это. Вопрос в том, , на какой сервер вам следует позвонить, чтобы минимизировать стоимость?

Для этого есть много решений на rnet, любая конечная точка, которая отвечает с быстрым статусом 204, является идеальной, Например:

  • вызов на сервер Google (поскольку он наиболее проверенный в бою (?))
  • вызов конечной точки сценария с кэшированием JQuery (даже если сервер не работает) вы все равно сможете получить скрипт, если у вас есть соединение)
  • попробуйте извлечь изображение со стабильного сервера (например: https://ssl.gstatic.com/gb/images/v1_76783e20.png + отметка времени даты для предотвращения кэширования )

IMO, если вы запускаете это приложение React на сервере, имеет смысл обратиться к вашему собственному серверу, вы можете вызвать запрос на загрузку вашего /favicon.ico для проверки соединения ,

Эта идея (вызова собственного сервера) была реализована многими библиотеками, такими как Offline, is-reachable, и широко используется в сообщества. Вы можете использовать их, если не хотите писать все самостоятельно. (Лично мне нравится пакет NPM is-reachable за простоту.)

Пример:

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

Edit Testing Server Connection

I Верьте, что то, что у вас есть, уже хорошо, просто убедитесь, что оно вызывает правильную конечную точку.


Подобные вопросы SO:

2 голосов
/ 24 апреля 2020

Вы можете создать компонент для совместного использования между всеми подкомпонентами

используется:

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

}
2 голосов
/ 31 марта 2020

Настройка пользовательского перехвата

Установка перехвата с онлайн, офлайн событиями. затем обновите состояние и верните его. Таким образом, вы можете использовать его в любом месте вашего приложения с импортом. Убедитесь, что вы очистите с помощью функции возврата. Если вы этого не сделаете, вы будете добавлять все больше и больше прослушивателей событий каждый раз, когда компонент, использующий хук, монтирует. *

...