2016-10-01 20 views
8

私のReact/Reduxアプリケーションでは、アプリケーション全体で使用されるべき状態のコンポーネントを実装する問題に直面していることがよくあります。 単純なポップアップコンポーネントを、どのページでも再利用できるオープン/クローズ状態の例として考えてみましょう。その状態を管理するために(のネイティブsetStateを反応させるのためだけの構文糖である私はrecompose.withReducerを使用)Reusable react-reduxコンテナコンポーネント

  • 使用setStateと「ローカル」減速: は、ここに私が見つけた2可能なアプローチです。あなたのページの他の部分でコンポーネントの状態を変更する必要があるまで、簡単に再利用できます(閉じるポップアップの場合)。そしてあなたは状態を変えるためにいくらかの還元行為を呼び出すことはできません。

  • コンポーネントの状態をReduxストアに保存します。このようなアプローチでは、コンポーネントツリーの任意の場所にあるclosePopupAction({ id })を呼び出して状態を変更することができます。しかし、コンポーネントがマウントされて削除されると、減速機(ポップアップのフォルダに入れたい)をルートレデューサーに置く必要がありますコンポーネントがアンマウントされたとき。さらに、ページ内に複数のポップアップがあり、それぞれに独自の状態があります。

誰も同じような問題に直面しましたか?

+0

をあなたが何を求めているのか分かりません。どのソリューションが他のソリューションよりも優れているか尋ねていますか? – wuct

+1

両方の方法では動作しません。だから私は他の何かを探しています –

+0

あなたは何を達成したいと思いますか?私は両方の方法が成功していると信じています'recompose'の場合、他のサブツリーで' setState'を呼び出そうとすると 'withState()'を上位のノードに持ち込むことができます。 'redux'の場合、状態が極端に大きくならない限り、減速機を取り外す必要はありません。 – wuct

答えて

1

私はあなたがreduxのコンポーネントの状態を保つべきだと思います。あなたは、このコンポーネントの減速を作成し、このようにcombineReducers機能を使用することができます。

rootReducer = combineReducers({ 
    moduleA: combineReducers({ 
     popupA: popupReducer("id1"), 
     popupB: popupReducer("id2") 
    }), 
    moduleB: combineReducers({ 
     popupA: popupReducer("id3") 
    }) 
    }) 
}); 

あなたはclosePopupAction(「ID1」)を呼び出すときに減速がIDをチェックし、状態の適切な部分を変更することができます。

PS:Idがより良い方法で提供する必要があります:)

+2

Reduxでは、状態の正確な構造を指定する必要があります。しかし、もし私がポップアップのリストを持っていたら?それぞれに独自の状態があります –

+0

初期状態のみを設定する必要があります。 2つのオプションがあります: 1. const initialState = {popups:[]} [todomvcの例](https://github.com/reactjs/redux/tree/master/examples/todomvc)によく似たものがあります) 2。const initialState = {popupsById:{}} とその後のアクションAddPopup(id、someState) state.popupsById [id] = someState objectAssign({}、state); –

+0

この回答は、別の問題の解決策です。 –

0

あなたは店の独自のスライスに、各コンポーネントの状態をマウントすることができます。

closePopupAction({ mountPath: 'popups.popup1' }) 

、あなたは、起動時に一度登録することができ、すべてのclosePopupActionアクション、処理するための唯一の減速が必要になります:

だからあなたclosePopupActionアクションは、そのマウントパスと呼ばれます

(state, { type, mountPath }) => { 
     if (type === 'CLOSE_POPUP_ACTION') { 
     // manipulate with the slice at `mountPath`, e.g. 
     return _.set(_.cloneDeep(state), `${mountPath}.isOpen`, false) 
     } 
     // ... 
    } 
関連する問題