如何在 react-native 中使用 Redux 来调度 NetInfo 连接更改操作?
How to use Redux in react-native to dispatch NetInfo connectivy change action?
我希望能够 'continuosly' 在我的 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 文档中看到:
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 中添加侦听器
就我个人而言,我喜欢将这种东西包装在一个 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
}
}
}
然后您可以从 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))
我希望能够 'continuosly' 在我的 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 文档中看到:
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 中添加侦听器
就我个人而言,我喜欢将这种东西包装在一个 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
}
}
}
然后您可以从 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))