[英]Switching From Online to Offline Stylesheets Based on Internet Availability
[英]Change state dynamically based on the external Internet connectivity - React (offline/online)
我有一个 React 组件,其中包括 Internet 连接的可用性标志。 UI 元素必须根据状态实时动态更改。 此外,函数的行为会随着标志的变化而不同。
我当前的实现使用间隔每秒使用 Axios 轮询远程 API,并相应地更新状态。 我正在寻找一种更精细、更有效的方法来完成这项任务,以最小的计算成本消除 1 秒的状态错误。 当且仅当设备具有外部 Internet 连接时才考虑在线
当前实现:
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} />;
}
}
编辑:
寻找能够检测外部 Internet 连接的解决方案。 设备可以连接到没有外部连接的 LAN。 所以,它被认为是离线的。 当且仅当设备可以访问外部 Internet 资源时才考虑在线。
您可以使用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.");
});
方法一:使用旧版浏览器 API - Navigator.onLine
返回浏览器的在线状态。 该属性返回一个布尔值,true 表示在线,false 表示离线。 只要浏览器连接到网络的能力发生变化,该属性就会发送更新。 当用户点击链接或脚本请求远程页面时,就会发生更新。 例如,当用户在失去 Internet 连接后不久单击链接时,该属性应返回 false。
您可以将其添加到您的组件生命周期中:
使用 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 状态响应的端点都是完美的,例如:
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>
);
}
}
我相信您目前所拥有的已经很好,只需确保它正在调用正确的端点。
类似的问题:
设置与在线、离线事件的挂钩。 然后更新一个状态并返回它。 通过这种方式,您可以通过导入在应用程序的任何位置使用它。 确保使用返回函数进行清理。 如果不这样做,每次使用钩子挂载的组件都会添加越来越多的事件侦听器。
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
您可以创建一个组件以在所有子组件之间共享
用过的:
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>
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.