我希望能够在我的本机应用程序中“连续”监视设备连接。
我已经在成功使用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));
};
};
但是,当连接更改时,我不知道如何调度新动作。
从本机文档中,我看到了这一点:
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,所以我认为这是错误的方式
您只需要在可以访问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像连接的组件一样,可以访问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
}
}
}
然后,您可以从MyApp
调度registerListeners()
和unregisterListeners()
,而不用在其中定义侦听器的详细信息:
// 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))