2016-12-04 21 views
0

最初に、私は2つのアプローチの間で変更している唯一のことはsetStateとReduxストアを経由することです。他のもの、つまりコンポーネントなどを変更しないでください。setStateは機能しますが、reduxストアの更新はありません

私はsetStateアプローチを使用するとモーダルを閉じることができますが、ストアを通過すると閉じません。どんな考え?ここで

は私の減速だ:ここで

import 'babel-polyfill'; 
import * as types from '../actions/actionTypes'; 

const initialState = { 
    modals: { 
     "modal1": { isDisplayed: true }, 
     "modal2": { isDisplayed: false } 
    } 
}; 

export default (state = initialState, action) => { 

    switch (action.type) { 

     case types.SET_IS_DISPLAYED_MODAL : 
      return Object.assign({}, state, { 
       modals: action.modals 
      }) 

     default: return state 
    } 
    } 
} 

は、モーダルを閉じることになっている私のonClickアクションの2つのバージョンがあります。

これは、SETSTATEのバージョンであり、それが動作します:

displayModal(modalId, value) 
{ 
    let modals = this.props.modals; 
    modals[modalId].isDisplayed = value; 
    return setState({modals: modals}); 
} 

そしてここでは、Reduxの店を通過し、それが私のモーダルを閉じないバージョンです。

displayModal(modalId, value) 
{ 
    let modals = this.props.modals; 
    modals[modalId].isDisplayed = value; 
    return this.props.actions.displayModal(modals); 
} 

あり、アクションに多くはないですが、ここにある:私は、ところで

render() { 

    return(
    <div> 
     <div>Some info...</div> 
     {this.props.modals["modal1"].isDisplayed 
     ? <Modal1 /> 
     : null} 

     {this.props.modals["modal2"].isDisplayed 
     ? <Modal2 /> 
     : null} 
    </div> 
); 
} 

export const displayModal = (modals) => { 
    return { 
     type: types.SET_IS_DISPLAYED_MODAL, 
     modals 
    }; 
} 

あなたはそれが私のコンポーネントにどのように見えるかを確認するだけので、ここにあります私はアクションとレデューサーを打つことを知っている。また、私がmapStateToPropsにデバッガを置くと、モーダルの更新された状態でそれを打つことになることも知っています。だから私は、アクションとレデューサーの両方が、彼らが想定していることをやっていることを知っています。

更新: 私は何か試してみましたが、これで問題は解決しました。私はmapStateToPropsに最後の行を追加し、私のコンポーネントでセクションを更新:

function mapStateToProps(state) { 

    return { 
     modals: state.modals, 
     isModal1Displayed: state.modals["modal1"].isDisplayed // Just added this line 
    } 
} 

とする私のコンポーネントのコードを変更:まず、はReduxのリデューサに状態を変異させることはありません

render() { 

    return(
    <div> 
     <div>Some info...</div> 
     {this.props.isModal1Displayed 
     ? <Modal1 /> 
     : null} 
    </div> 
); 
} 
+0

コンポーネントを接続しているコード部分を追加できますか? – diedu

+0

元の投稿を更新しました。 this.props.modals ["modal1"]。isDisplayedをチェックする代わりに、mapStateToPropsに新しいpropを作成しました。私はmapStateToPropsで少しファンキーに見えますが、うまくいきます。なぜ初期のコードが失敗したのか? – Sam

答えて

1

- 正しく動作し、変更を正しく検出するには、純粋な関数でなければなりません。同じルールがあなたが小道具を持っているオブジェクトに適用されます。

アクションをストアにディスパッチし、ストアを新しい状態に縮小するようにコードを変更する必要があります。

まず、アクションをディスパッチ:

displayModal(modalId, value) 
{ 
    this.props.actions.displayModal(modalId, value); 
} 

あなたの行動は、表示または非表示にするモーダル情報を運ぶ:

export const displayModal = (modalId, value) => { 
    return { 
     type: types.SET_IS_DISPLAYED_MODAL, 
     modalId, 
     value 
    }; 
} 

次に、あなたがそれを減らすことができます

export default (state = initialState, action) => { 
    switch (action.type) { 
     case types.SET_IS_DISPLAYED_MODAL : 
      return Object.assign({}, state, 
      { 
       modals: Object.assign({}, state.modals, 
       { 
        [action.modalId]: { isDisplayed: action.value } 
       }) 
      }) 

     default: return state 
    } 
} 

ように今ここに多くの定型文があることがわかります。 ES6とES7では、減速機をobject spread operatorで書き換えたり、Immutable.js libraryを使用したりすることができます。これは、階層の深いプロパティの設定に役立ちます。

オブジェクト広がりオペレータとのリデューサーは次のようになります。

export default (state = initialState, action) => { 
    switch (action.type) { 
     case types.SET_IS_DISPLAYED_MODAL : 
      return { 
       ...state, 
       modals: { 
        ...state.modals, 
        [action.modalId]: { isDisplayed: action.value } 
       } 
      } 

     default: return state 
    } 
} 

あなたの修正作業の理由あなたは自分自身を求めることができます。私に説明させてください。 アクションをの位置に変更して、Redux by mutating状態にアクションをディスパッチすると、モーダル状態が変更されます。その後、アクションはディスパッチされ、縮小され、mapToPropsが再び呼び出されます。おそらくconnect高次コンポーネントで参照チェックがあり、オブジェクトではなくmodalに変更したので、同じ参照=コンポーネントが再レンダリングされません。 isModal1Displayedフィールドを追加すると、実際に最適化が無効になります。これは、参照チェックではなくブール値の比較が行われ、コンポーネントが再レンダリングされるためです。

私はReduxとその原則を理解するのに役立つことを願っています。

+0

私は実際に少し混乱しています。あなたの回答の最初の部分を理解して同意します。私がreduxの店を通過するとき、私はあなたのレデューサーコードで見ることができるように、状態をまったく変えていません。なぜ私の修正が機能するのか話したところで、あなたの回答の2番目の部分を読みましたが、私はあなたのことを理解できませんでした。唯一の違いは、私の修正では、コンポーネント内の値(this.props.modals [modal1] .isDisplayed)にアクセスするのではなく、mapStateToPropsの新しい小道具にmodal1のisDisplayed値を割り当てます。どちらの場合も、値はモーダルオブジェクトから取得されます。 – Sam

+0

続き:どちらのアプローチでも、私は自分の値をモーダルから引き出すという事実は、自分のアクション/レデューサーコードがうまく動作し、モーダルの状態を正常に更新することを伝えます。私はなぜthis.props.modals [modal1] .isを使ってmodal1にisDisplayedにアクセスできないのか分かりません。私のコンポーネントの中に表示されています。 – Sam

+1

Redux内部の仕組み、特に 'connect'コンポーネントが知られているので、説明するのは難しいです。 'modals [modalId] .isDisplayed = value;'を実行することによって 'displayModal'の状態を変更します。' modals'は同じメモリ位置を参照/参照しているオブジェクトです。後で、あなたのアクションが処理されるとき、Reduxはあなたのコンポーネントを再描画しようとしますが、 'modals' ===' modals'を見て、その場合は何もしません。そのため、コンポーネントが更新されなかったのです。 –

関連する問題