Динамічно змінюйте стан на основі зовнішнього підключення до Інтернету - React (офлайн / онлайн)


10

У мене є компонент React, який включає прапор наявності підключення до Інтернету. Елементи інтерфейсу повинні динамічно змінюватися відповідно до стану в режимі реального часу. Також функції поводяться по-різному зі змінами прапора.

Моя поточна реалізація опитує віддалений API, що використовує Axios щосекунди, використовуючи інтервал і відповідно оновлює стан. Я шукаю більш детальний та ефективний спосіб виконати це завдання для видалення 1-секундної помилки стану при мінімальних обчислювальних витратах. В Інтернеті вважається, якщо і тільки якщо пристрій має зовнішнє підключення до Інтернету

Поточна реалізація:

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

Відредаговано:

Шукаєте рішення, здатне виявити зовнішнє підключення до Інтернету. Пристрій може підключитися до локальної мережі, яка не має зовнішнього з'єднання. Отже, це вважається офлайн. В Інтернеті вважається, якщо і лише тоді, коли пристрій має доступ до зовнішніх ресурсів Інтернету.


2
вам потрібно знати, чи ви офлайн чи онлайн? або яке підключення до Інтернету?
tudor.gergely

Так. В основному онлайн або офлайн.
Ніланка Маной

чи можете ви змінити API, щоб він відкривав з'єднання веб-розетки?
yadejo

Відповіді:


2

Перший спосіб: Використання застарілого API браузера - Navigator.onLine

Повертає статус веб-переглядача в Інтернеті. Властивість повертає булеве значення з істинним значенням в Інтернеті та помилковим значенням офлайн. Властивість надсилає оновлення щоразу, коли здатність браузера підключатися до мережі змінюється. Оновлення відбувається, коли користувач переходить посилання або коли сценарій вимагає віддалену сторінку. Наприклад, властивість повинна повернути помилкову, коли користувачі натискають на посилання незабаром після втрати з’єднання з Інтернетом.

Ви можете додати його до життєвого циклу компонентів:

Грайте з наведеним нижче кодом за допомогою інструментів для розробників Chrome - переключіть "Інтернет" на "Офлайн" на вкладці "Мережа".

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>


Однак я думаю, що це не те, чого ви хочете, ви хотіли перевірити підключення в реальному часі .

Спосіб другий: перевірка підключення до Інтернету за допомогою нього

Єдине тверде підтвердження, яке ви можете отримати, якщо працює зовнішнє підключення до Інтернету, - це скористатися ним. Питання в тому, який сервер вам слід зателефонувати, щоб мінімізувати витрати?

Для цього в Інтернеті є багато рішень, будь-яка кінцева точка, яка відповідає швидким статусом 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>
    );
  }
}

Редагування підключення до тестування сервера

Я вважаю, що у вас є вже добре, просто переконайтесь, що воно називає правильну кінцеву точку.


Подібні питання ТА:


8

Ви можете використовувати 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

Налаштуйте спеціальний гачок

Налаштуйте гачок із подіями в Інтернеті, офлайн потім оновіть стан і поверніть його. Таким чином, ви можете використовувати його будь-де у вашому додатку з імпортом. Переконайтесь, що ви чистите за допомогою функції повернення. Якщо ви цього не зробите, ви додаватимете все більше та більше слухачів подій щоразу, коли компонент використовує кріплення гака.

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
}

Для цього просто імпортуйте вищевказаний гачок і назвіть його так.

const isOnline = onlineHook(); // true if online, false if not


3
Якщо ви використовуєте сервісну розетку, як-от firebase, ви можете використовувати вбудований випадок, який охоплює підключення до Інтернету.
Джо Ллойд

чи можете ви надати базовий скелет коду для запропонованого підходу.
Ніланка Маной

2

Ви можете створити компонент для спільного використання всіх підкомпонентів

використовується:

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

}

Ви забули видалити слухача подій?
gautamits
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.