2017-01-01 20 views
0

状況 私はreduxsを使用してreactjsアプリを持っています。私はコンテナとプレゼンテーションコンポーネントを持っています。私のプレゼンテーションコンポーネントは、単純なテキスト入力フィールドの配列でフォームをレンダリングし、コンテナからプレゼンテーションコンポーネントに 'onChange'コールバック関数を渡して、テキストフィールドのいずれかが入力されたときに還元状態を変更するアクションを送出します。reactjsプレゼンテーションcomopnentは還元状態の変更で再レンダリングされません

問題 は、プレゼンテーションコンポーネントが正常にReduxの状態からテキストフィールドプレゼンテーションコンポーネントマウント用の正しい値をレンダリングするが、私はフィールドに入力すると更新されません。コンテナのmapStateToPropsのプレゼンテーションコンポーネントに渡されたプロップを記録すると、onChange関数がストアに正しくディスパッチされており、リフィックス状態が正しく更新されていることがわかります。しかし、プレゼンテーションコンポーネントは再レンダリングされませんので、テキストフィールドでの入力はビューを更新しません(何もしません)。

formConnector

import { connect } from 'react-redux' 
    import Form from '../components/Form' 
    import { changeElementValue } from '../actions/actions' 

    const mapStateToProps = (state) => { 
     //e.g. state.elements = [{id:"email", value:"[email protected]"}] 
     let props = { 
      elements: state.elements, 
     } 

     //state and props.elements.{id}.value changes successfully when I 
     //type in one of the input fields, but 
     //the the Form component is not re-rendered 
     console.log(props) 

     return props 
    } 

    const mapDispatchToProps = (dispatch) => { 
     return { 
      onElementChange: (id, value) => { 
       dispatch(changeElementValue(id, value)) 
      }, 
     } 
    } 

    export default connect(mapStateToProps, mapDispatchToProps)(Form) 

フォーム減速

function formReducer(state = initialState, action = null) { 
     switch(action.type) { 
      case types.CHANGE_ELEMENT_VALUE: 
       let newState = Object.assign({}, state) 
       newState.elements[action.id].value = action.value 
       return newState 

      default: 
       return state; 
     } 
    } 

アクション

import * as types from './actionTypes' 

    export function changeElementValue(id, value) { 
     return { type: types.CHANGE_ELEMENT_VALUE, id, value } 
    } 
+0

は、コンポーネントのコードと減速を添付することはできますか?あなたは店が変わったと確信していますか?あなたが取っている価値はstate.textField.valueに設定されていて、減速機が何を変えているのか分からないようです(idとそれが通過するID)。私は問題がその地域にあると確信している。 – Kinnza

+0

@Kinnza見てくれてありがとう。私はこの記事のコードを単純化するために問題を隠してしまったという恐ろしい気持ちを持っています。私のコネクターは、実際には、テキスト要素のセットをレンダリングする 'Form'コンポーネントを接続します。したがって、stateにはid値のペアの配列が含まれています。ここに貼り付けるだけの簡単なコードでサンプルを書き直してみましょうが、問題を再現できるように実行することができます。その間、州内の配列に埋め込まれた値の変更であるため、私のコンポーネントは状態の変化を認識していないと考えられますか?不変を使用する必要がありますか? – xanld

+0

OK、私は単純化されたコードを使用してプロトタイプを構築する機会はまだありませんでしたが(必要に応じて後で試してみます)、実際のアプリで何が起きているのかをよりよく表現できるようにサンプルを更新しました。今レンダリングされている要素の配列があります。もう一度、要素配列の値の1つが更新されたときの状態への変化を検出していないため、プレゼンテーションコンポーネント(フォーム)が再レンダリングされていないという私の感想はどうですか? – xanld

答えて

1

コメントで説明したように、この状態の突然変異によるものです。

は、次のように減速コードを変更してください:

エレガント
case types.CHANGE_ELEMENT_VALUE: { 
    const newElements = state.elements.map(function(el, index) { 
     return action.id === index 
      ? Object.assign({}, el, { value: action.value }) 
      : el; 
    }); 
    return Object.assign({}, state, { elements: newElements); 
} 

以上:

case types.CHANGE_ELEMENT_VALUE: 
    return { ...state, elements: state.elements.map((el, index) => (
     action.id === index ? { ...el, value: action.value } : el 
    )} 
+0

こんにちは、これは私の質問に答えているので、答えとしてマークしました。根本的な問題は、返された状態が古い状態への参照を含んでいたため、反応しなかったために変更が検出されなかったことです。この回答は私がこれを識別するのを助け、OB3キンザとアッサンには非常に感謝しています。実際のところ、私は実際のコードにこのソリューションを直接適用することはできないので、私は自分のコード例を悩ましました。だから私はここで新しい投稿でより正確に問題を再構成しました:http://stackoverflow.com/questions/41418623/change-value-deep-in-redux-state再度、感謝します。 – xanld

関連する問題