有两个事件监听器在监视网络状态时显然很有用:
1. window.addEventListener('online', console.log('Online'));
2. window.addEventListener('offline', console.log('Offline'));
但是我不确定在哪里注册和使用它们。当我在componentDidMount
中使用它们时,没有任何用处,因为只有安装了组件,监视才会发生。我想在一处监视网络状态,并在整个应用程序中使用它。为此,在redux中调度网络状态会更有帮助。但是问题是在哪里可以听到这些事件。
答案 0 :(得分:1)
带有类组件的简化示例:
// In your main App component
componentDidMount() {
window.addEventListener('online', () => this.props.setConnectivity('online'));
window.addEventListener('offline', () => this.props.setConnectivity('offline'));
// You don't need to worry about removeEventlistener if your main App component never unmounts.
}
// Action
const setConnectivity = (status) => ({
type: 'SET_CONNECTIVITY',
payload: status === 'online'
})
// Reducer
const connectivityReducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_CONNECTIVITY':
return {
...state,
isOnline: action.payload
};
}
};
// To let a component know about the connectivity status, simply use the flag from state:
const mapStateToProps = (state) => ({
isOnline: state.connectivity.isOnline
});
// To react to status changes in any other component:
componentDidUpdate(prevProps) {
const { isOnline } = this.props;
if (!prevProps.isOnline && isOnline) {
// We went online
} else if (prevProp.isOnline && !isOnline) {
// We went offline
}
}
答案 1 :(得分:1)
这是React + Redux中在线/离线状态指示器的有效示例。
神奇之处在于拥有一个组件,该组件在组件的online
事件中为componentDidMount
事件添加了事件侦听器。然后,它通过Redux调度操作以更新商店中的在线状态。容器组件(在此示例中为MainContainer
)可以将全局商店状态映射到道具,并且任何表示性组件都可以响应此属性更改而更新。
如果要使用Chrome在此页面上测试此在线指示器,请运行以下代码段:运行代码段,然后启动开发工具( F12 ),然后切换设备工具栏( Ctrl + Shift + M )(或“开发工具”窗口左上方的第二个图标),切换到响应式布局,然后根据需要在栏中切换在线/离线状态(如下图所示):
function rootReducer(currentState, action) {
currentState = currentState || { status: true }; // Initial State
switch (action.type) {
case 'SET_ONLINE_STATUS':
return { ...currentState, status: action.status };
default:
return currentState; // Always return the state
}
}
// Action Creators:
function setOnlineStatus(status) {
return { type: 'SET_ONLINE_STATUS', status };
}
// Create Store
var rootStore = Redux.createStore(rootReducer);
// Map state and dispatch to props
function mapStateToProps(state) {
return {
status: state.status
};
}
function mapDispatchToProps(dispatch) {
return Redux.bindActionCreators({
setOnlineStatus: setOnlineStatus
}, dispatch);
}
// Connection indicator pure functional presentational component
var ConnectionIndicator = (props) => {
return (<div>You are: {props.status ? 'online' : 'offline'}</div>);
};
var Main = React.createClass({
render: function () {
return (<div>
<ConnectionIndicator status={this.props.status} />
</div>);
}
});
var OnlineWatcher = React.createClass({
render() { return null; },
componentDidMount() {
window.addEventListener('online', () => {
this.props.setOnlineStatus(true);
})
window.addEventListener('offline', () => {
this.props.setOnlineStatus(false);
})
}
});
// Container components (Pass props into presentational component)
var MainContainer = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(Main);
var OnlineWatcherContainer = ReactRedux.connect(mapStateToProps,
mapDispatchToProps)(OnlineWatcher);
// Top-Level Component
var App = React.createClass({
render: function () {
return (
<div>
<MainContainer />
<OnlineWatcherContainer />
</div>
);
}
});
// Render to DOM
var Provider = ReactRedux.Provider; // Injects store into context of all descendents
ReactDOM.render(
<Provider store={rootStore}>
<App />
</Provider>,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.5/react-redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.13.0/polyfill.js"></script>
<div id="container">
<!-- Yield to React -->
</div>
注意::在生产代码中,您还应该在online
函数中取消订阅offline
和componentWillUnmount
事件。
我以this fiddle为起点。
答案 2 :(得分:1)
我建议使用此very new library
然后,您可以使用useNetworkStatus
来获取所需的内容,例如:
import React from 'react';
import { useNetworkStatus } from 'react-adaptive-hooks/network';
const MyComponent = () => {
const { effectiveConnectionType } = useNetworkStatus();
let media;
switch(effectiveConnectionType) {
case 'slow-2g':
media = <img src='...' alt='low resolution' />;
break;
case '2g':
media = <img src='...' alt='medium resolution' />;
break;
case '3g':
media = <img src='...' alt='high resolution' />;
break;
case '4g':
media = <video muted controls>...</video>;
break;
default:
media = <video muted controls>...</video>;
break;
}
return <div>{media}</div>;
};
effectiveConnectionType
-如果网络发生变化,则会发生变化,
navigator.connection.addEventListener('change', func)
-这也会在online
和offline
答案 3 :(得分:0)
首先,您应该具有带有操作和简化器的redux存储。您可以连接要存储的每个组件,并使用此事实来源。您可以在https://react-redux.js.org/introduction/quick-start
处找到文档和说明。实际上,您可以找到使用在线状态Integrating Navigator.onLine into React-Redux
的示例