2017-05-29 7 views
1

すべてのコンポーネントで、ユーザーがインターネットに接続しているかどうかをテストします。React Native with ReduxでのNetInfoミドルウェアの使用

私はNetInfoを各コンポーネントに使用できますが、私はreduxを使用しているので、ミドルウェア(?)で簡単にできると思いました。

AppReducerがちょうどcombineReducers(navReducer, netInfoReducer, ...)ここで私は

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)); 

を使用していました。

これはうまくいくようですが、これが十分に機能するかどうか本当に心配です。それは一度だけ実行されているようだが、私はリスナーなどを削除することは決してない。

これは、すべてのコンポーネントに変数isConnectedを取り込む場合に通常行う方法ですか?

+0

HOCでこれと同じことを達成できませんでしたか?私は、HOCを使用すると複雑さが軽減され、結果としてあなたの心を緩和すると思います。ちょっとした考え。 –

答えて

3

私はこのためHigher-Order Componentを作成します。

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パッケージを使用して、反応しない特定の統計をコピーする必要があります。

+0

これは良い解決策ですが、 'MyComponent'には小道具しか与えません。私は私のアプリのすべてのコンポーネントの小道具にアクセスできるようにしたい。 – Jamgreen

+0

'withNetInfo()'で任意のコンポーネントを飾ることができます。それはさらにあなたにコントロールを与えます。 – Kerumen

+0

しかし、すべての単一コンポーネントのマウントにイベントリスナーを追加すると、パフォーマンス上の問題は生じませんか? – Jamgreen

1

ミドルウェアを使用してreduxストアに「isConnected」を保持するとパフォーマンスに問題はありませんが、リスナーが1回だけ追加されていることを確認してください。私はそれを達成するためにhttps://github.com/michaelcontento/redux-middleware-oneshotを使用します。

1

私はミドルウェアも考慮しましたが、サブ/ unsubをどのように扱うかを恐れていました。私は、MainNavigatorの残りのアプリケーションを保持する私のAppContainerクラスのcomponentDidMountcomponentWillUnmountのリスナの追加と削除を行うことに決めました。このクラスのライフサイクルはアプリのライフサイクルに従っている必要があります。したがって、正しくサブ/サブブラブするようにしてください。しかし、私はまた、還元のアクションを使用してステータスを設定し、関連するビューでそれを聞いて「接続なし」のバナーを表示しようとしています。

関連する問題