我希望能够连续不断地'在我的react-native应用程序中监视设备连接。
我已经成功使用了redux-thunk和redux。
其实我能够做到这一点
import { NetInfo } from 'react-native';
import {
CONNECTION_CHECKING,
CONNECTION_AVAILABLE,
CONNECTION_UNAVAILABLE,
} from './types';
export const connectionChecking = () => {
return (dispatch) => {
dispatch ({
type: CONNECTION_CHECKING
});
NetInfo.getConnectionInfo()
.then((connectionInfo) => {
console.log('Connection info: ', connectionInfo);
switch (connectionInfo.type) {
case 'cellular':
dispatch ({
type: CONNECTION_AVAILABLE,
payload: connectionInfo.type
});
break;
case 'wifi':
dispatch ({
type: CONNECTION_AVAILABLE,
payload: connectionInfo.type
});
break;
default:
dispatch ({
type: CONNECTION_UNAVAILABLE,
});
}
})
.catch((error) => console.warn(error));
};
};
但是,当连接发生变化时,我不知道如何发送新动作。
从react-native doc我看到了:
NetInfo.addEventListener(
'connectionChange',
handleConnectivityChange
);
但是......如何在事件监听器中调度动作?
我尝试将其添加到同一个操作文件
中NetInfo.addEventListener(
'connectionChange', (connectionInfo) => {
return (dispatch) => {
console.log('Connection info changed ', connectionInfo);
switch (connectionInfo.type) {
case 'cellular':
case 'wifi':
dispatch ({
type: CONNECTION_AVAILABLE,
payload: connectionInfo.type
});
break;
default:
dispatch ({
type: CONNECTION_UNAVAILABLE,
});
}
};
}
);
我没有结果,没有console.log,所以我认为这是错误的方式
答案 0 :(得分:4)
您只需要在某处设置可以访问dispatch
功能的事件监听器。
最简单的事情(允许干净的取消订阅)是将它们设置在最顶层的连接组件中:
class MyApp extends Component {
constructor(props) {
super(props);
// Dispatch an action from your event handler (and do whatever else)
this._handleConnectionChange = (connectionInfo) => props.dispatch({
type: 'CONNECTION_CHANGE',
connectionInfo
});
NetInfo.addEventListener('connectionChange', this._handleConnectionChange);
}
componentWillUnmount() {
NetInfo.removeEventListener('connectionChange', this._handleConnectionChange);
}
}
export default connect()(MyApp); // MyApp must be connected
就我个人而言,我喜欢将这种东西包裹在一个thunk中,以避免听众处理混乱的组件。这里重要的一点是thunk,如连接组件,可以访问dispatch
,因此通过在thunk内部定义监听器,我们可以调度动作(或更多thunk)以响应更改。
// connectionActions.js
let handleConnectionChange;
export function registerListeners() {
return (dispatch) => {
handleConnectionChange = (connectionInfo) => {
dispatch(connectionChanged(connectionInfo));
}
NetInfo.addEventListener('connectionChange', handleConnectionChange);
}
}
export function unregisterListeners() {
return (dispatch) => {
handleConnectionChange && NetInfo.removeEventListener('connectionChange', handleConnectionChange);
}
}
function connectionChanged(connectionInfo) {
return (dispatch) => {
switch (connectionInfo.type) {
case 'cellular':
dispatch({
type: CONNECTION_AVAILABLE,
payload: connectionInfo.type
});
break;
// ...Other cases
}
}
}
然后您可以从registerListeners()
发送unregisterListeners()
和MyApp
,而不是在那里定义听众的详细信息:
// app.js
// ...other imports
import * as connectionActions from './connectionActions'
class MyApp extends Component {
constructor(props) {
super(props);
// Dispatch your thunk to take care of the registration
props.dispatch(connectionActions.registerListeners());
}
componentWillUnmount() {
this.props.dispatch(connectionActions.unregisterListeners());
}
}
export default connect()(MyApp)
在我有多个可能的顶级组件的应用程序中(例如,具有不同主页的不同构建变体,或者不是主导航器的登录屏幕),我喜欢采用这种样板并将其包裹起来在更高阶的组件中:
// hoc/withNetListeners.js
export default function withNetListeners(SourceComponent): {
class HOC extends React.Component {
constructor(props) {
super(props);
props.dispatch(connectionActions.registerListeners());
}
componentWillUnmount() {
this.props.dispatch(connectionActions.unregisterListeners());
}
render() {
return <SourceComponent {...this.props} />;
}
}
return hoistStatics(HOC, SourceComponent); // Package hoist-non-react-statics
}
然后在任何一个组件中充当你的根:
// app.js
class MyApp extends Component {
// ... Just your UI, no listeners ...
}
// Inject the listeners with a HOC. Make you `connect` last, because
// `withNetListeners` needs to be given access to `dispatch`.
export default connect()(withNetListeners(MyApp))