2017-01-01 87 views
0

情況 我有一個reactjs應用程序使用REDX。我有一個容器和一個演示組件。我的表示組件呈現一個包含簡單文本輸入字段數組的表單,並且我將一個'onChange'回調函數從容器傳遞給表示組件,該表單組件在輸入其中一個文本字段時調度動作以更改redux狀態。reactjs演示comopnent不重新渲染上REDX狀態變化

問題 呈現組件成功地呈現了正確的值從Redux的狀態文本字段呈現組件坐騎的時候,但是當我在字段中鍵入不更新。如果我將容器中傳遞給演示組件的道具記錄在mapStateToProps中,我可以看到onChange函數正確地分派到存儲區,並且正在更新redux狀態。但是當這種情況發生時,表示組件不會重新呈現,因此在文本字段中輸入不會更新視圖(鍵入什麼也不做)。

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謝謝你的採訪。我有一種可怕的感覺,爲了簡化這篇文章的代碼,我掩蓋了這個問題。我的連接器實際上連接了一個呈現一組文本元素的「表單」組件。所以state包含一個id值對的數組。我將用代碼重新編寫示例來簡單地粘貼到此處,但我可以運行以確保它複製問題。與此同時,可以想象我的組件不會識別狀態變化,因爲它是對狀態內的數組中的數值的更改?應該使用不可變的? – xanld

+0

好的,我還沒有機會使用我的簡化代碼構建原型(如果需要,稍後會嘗試),但是我已經更新了示例,以便它更真實地表示應用程序中發生的情況。現在有一組元素被渲染。再一次,對於我的預感,你認爲表單組件(Form)沒有被重新渲染,因爲它沒有檢測到元素數組中某個值更新時狀態的變化? – 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 Kinnza和Assan。實際上,我弄糟了我的代碼示例,我的問題仍然存在,因爲我無法直接將解決方案應用到我的實際代碼中。所以我在這裏的一個新帖子更準確地重新構建了這個問題:http://stackoverflow.com/questions/41418623/change-value-deep-in-redux-state。再次感謝。 – xanld