簡體   English   中英

如何在react-native中使用Redux調度NetInfo連接更改動作?

[英]How to use Redux in react-native to dispatch NetInfo connectivy change action?

我希望能夠在我的本機應用程序中“連續”監視設備連接。

我已經在成功使用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中添加偵聽器

我個人喜歡將這種東西包裝在一個大塊的東西中,以免聽眾處理混亂的組件。 這里的重點是,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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM