在Redux中使用React Native中的NetInfo中间件

我想testing所有组件是否用户连接到互联网。

我可以在每个组件中使用NetInfo ,但是由于我使用的是redux ,所以我认为使用中间件(?)可以更容易。

我用过

 import { createStore, applyMiddleware } from 'redux'; const netInfo = store => next => action => { const listener = (isConnected) => { store.dispatch({ type: types.NET_INFO_CHANGED, isConnected, }); }; NetInfo.isConnected.addEventListener('change', listener); NetInfo.isConnected.fetch().then(listener); return next(action); }; const store = createStore(AppReducer, applyMiddleware(netInfo)); 

其中AppReducer只是combineReducers(navReducer, netInfoReducer, ...)

这似乎工作,但我真的很担心,如果这performance不错。 它似乎只运行一次,但我从来没有删除监听或任何东西。

如果你想用isConnectedvariables填充所有的组件,你通常会这么做吗?

我会为此创build一个高阶组件 :

 import React, { Component } from 'react'; import { NetInfo } from 'react-native'; function withNetInfo(WrappedComponent) { return class extends Component { constructor(props) { super(props); this.state = {}; this.handleChange = this.handleChange.bind(this); NetInfo.isConnected.fetch().then(this.handleChange); } componentDidMount() { NetInfo.isConnected.addEventListener('change', this.handleChange); } componentWillUnmount() { NetInfo.isConnected. removeEventListener('change', this.handleChange); } handleChange(isConnected) { this.setState({ isConnected }); } render() { return <WrappedComponent isConnected={this.state.isConnected} {...this.props} />; } } } export default withNetInfo; 

然后你可以打包你想渲染的任何组件:

 class MyComponent extends Component { render() { const { isConnected } = this.props; return( <View> <Text> {`Am I connected? ${isConnected}`} </Text> </View> ); } } export default withNetInfo(MyComponent); 

奖励:如果你想保留原始组件的静态方法(如果你已经定义了一些),你应该使用包hoist-non-react-statics来复制无反应的特定静态:

 import React, { Component } from 'react'; import { NetInfo } from 'react-native'; import hoistStatics from 'hoist-non-react-statics'; function withNetInfo(WrappedComponent) { class ExtendedComponent extends Component { constructor(props) { super(props); this.state = {}; this.handleChange = this.handleChange.bind(this); NetInfo.isConnected.fetch().then(this.handleChange) } componentDidMount() { NetInfo.isConnected.addEventListener('change', this.handleChange); } componentWillUnmount() { NetInfo.isConnected. removeEventListener('change', this.handleChange); } handleChange(isConnected) { this.setState({ isConnected }); } render() { return <WrappedComponent isConnected={this.state.isConnected} {...this.props} />; } } return hoistStatics(ExtendedComponent, WrappedComponent); } export default withNetInfo; 

使用中间件在redux存储中保留“isConnected”不应该存在性能问题,但是您需要确保只添加一次侦听器。 我使用https://github.com/michaelcontento/redux-middleware-oneshot实现&#x3002;

我也考虑过中间件,但也担心如何处理sub / unsub。 我已经决定去添加和删除我的AppContainer类的componentDidMountcomponentWillUnmount中的监听器,该监听器在我的MainNavigator中包含应用程序的其余部分。 这个类的生命周期应该遵循这个应用程序的,因此确保正确的子/取消。 不过,我也正在用redux行动来设定地位,并在相关的意见中聆听,以显示“无连线”的标语。