2015-05-11 53 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