2015-05-11 34 views
2

我發現反應不更新數組中的元素時更改組件。相反,一個新的數組必須被克隆並放置。例如,我有一個_suggestedPeople的數組。當點擊代表這些人中的一個的UI元素時,我想通過致電selectPerson進行註冊。如何更新React組件的數組?

我希望作出反應這樣做後更新:

selectPerson: function(personID, selected) { 
    var person = _.find(_suggestedPeople, {id: personID}); 
    if (person) { 
     person.selected = selected; 
    } 
    return person; 
    }, 

不過,我最後都這樣做,這似乎是不必要的:

selectPerson: function(personID, selected) { 
    var index = _.findIndex(_suggestedPeople, {id: personID}); 
    var found = index !== -1; 
    if (found) { 
     var people = _.cloneDeep(_suggestedPeople); 
     people[index].selected = selected; 
     _suggestedPeople = people; 
    } 
    return found; 
    }, 

這是後者更新的正確方法React組件的數組數據?或者我錯過了什麼?

+0

也許不同的方法更適合不變性範式。例如。將對所選人員對象的引用存儲在組件的另一個屬性中,而不是改變人員對象。 –

+0

爲什麼不只是在發生新選擇時觸發更新? React不會跟蹤對象的屬性,所以僅僅設置對象的選擇將不起作用。例如,您可以調用['forceUpdate'](http://facebook.github.io/react/docs/component-api.html#forceupdate)。 – WiredPrairie

+0

對不起,我發現它有點難以遵循你的代碼片斷,但我認爲你應該將選定的人存儲在組件狀態(或者它的父對象的狀態取決於實現哪個組件),並強制通過調用'this.setState({_ suggestedPeople:people,selectedPerson:person})'重新渲染。有一個小提琴http://jsfiddle.net/map5vf94/11/在這個問題的答案,這可能是你想要做的 - http://stackoverflow.com/questions/30042657/reactjs-calculate-state- on-change-to-components-props-as-a-result-of-parent-re-r –

回答

0

您似乎沒有使用React的內置狀態管理。如果你這樣做,你們兩種更新狀態方法之間的中間立場將起作用。一個組件在狀態或屬性改變時將會重新呈現。

通過實施

getInitialState: function() { 

    var whereverItComesFrom = [ 
     {id: 1, selected: false}, 
     {id: 2, selected: false} 
    ]; 

    return { 
     suggestedPeople: whereverItComesFrom 
    } 
} 

渲染方法初始化組件的狀態,從這個渲染:

render: function() { 
    var _this = this; 
    var peeps = this.state.suggestedPeople.map(function(person, index){ 
     return <label key={index}><input type='checkbox' checked={person.selected} value={person.id} onChange={_this.handlePersonClick}/>{person.id}</label>; 
    }); 

    return <div>{peeps}</div>; 
}, 

handlePersonClick可以是你的方法合併:

handlePersonClick: function(e) { 
    var selectedId = e.target.value; 
    var checked = e.target.checked; 
    var peeps = this.state.suggestedPeople; 
    var index = _.findIndex(peeps, {id: selectedId}); 

    peeps[index].selected = checked; 

    this.setState({suggestedPeople: peeps}); 

}

全部jsfiddle

+0

這不會做任何事情......在這個問題上修改對象不會觸發狀態改變。你必須替換整個數組元素。 – tomitrescak

+0

@tomitrescak它工作得很好,因爲對'setState'的調用強制渲染。從文檔:'setState()將始終觸發重新呈現,除非條件呈現邏輯在shouldComponentUpdate()'中實現。 – neverfox

+0

請不要這樣做,你不應該改變當前的狀態對象。'setState'不會立即重新渲染你的組件,但你立即改變了狀態,這將很難找到錯誤! – caesay