Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何更新React组件的数组?_Javascript_Arrays_Reactjs_Reactjs Flux_Flux - Fatal编程技术网

Javascript 如何更新React组件的数组?

Javascript 如何更新React组件的数组?,javascript,arrays,reactjs,reactjs-flux,flux,Javascript,Arrays,Reactjs,Reactjs Flux,Flux,我发现当数组中的元素发生更改时,React不会更新组件。相反,必须克隆一个新阵列并将其放置到位 例如,我有一个\u suggestedPeople数组。单击表示这些人之一的UI元素时,我想通过调用selectPerson来注册 我希望在执行此操作后做出更新: selectPerson: function(personID, selected) { var person = _.find(_suggestedPeople, {id: personID}); if (person)

我发现当数组中的元素发生更改时,React不会更新组件。相反,必须克隆一个新阵列并将其放置到位

例如,我有一个
\u suggestedPeople
数组。单击表示这些人之一的UI元素时,我想通过调用
selectPerson
来注册

我希望在执行此操作后做出更新:

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组件的数组数据的正确方法吗?还是我遗漏了什么

您似乎没有使用React的内置状态管理。如果你这样做了,那么在你的两种更新状态的方法之间找到一个折衷的方法将会奏效。当组件的状态或属性发生任何更改时,组件将重新渲染

编辑:此代码已过时,不是良好做法。请参阅下面更新的JSFIDLE

通过实现初始化组件状态

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>;
},
}

编辑:以上是非常不知情的早期反应为我。我已经更新了下面的fiddle链接,它应该是解决这个问题的一个很好的基本示例


完整的

也许另一种方法更适合不变性范式。例如,将对所选人员对象的引用存储在组件的另一个属性中,而不是对人员对象进行修改。为什么不在发生新选择时触发更新?React不会跟踪对象的属性,因此仅设置对象的“选定对象”将不起作用。例如,您可以调用。很抱歉,我发现在上下文之外跟踪代码片段有点困难,但我认为您应该将所选人员存储在components状态(或其父级的状态,具体取决于在哪个组件中实现了
selectPerson
),并通过调用
this.setState强制重新渲染({建议的人:人,已选择的人:人})
。这个问题的答案中有一个小问题,这可能是您正在尝试做的-谢谢。起初我确实使用了
forceUpdate
,但我觉得我不应该这样做,而是我正在回避一个潜在的问题。可能不是这样。对于这个问题,我需要跟踪多个选择。您是否建议是否使用第二个列表?
selectedPeople
数组而不是
selectedPeople
对象?这不会起任何作用…在这件事上修改对象不会触发状态更改。您必须替换整个数组元素。@tomitrescak它工作正常,因为调用
setState
会强制进行渲染。从文档:
setStat除非在shouldComponentUpdate()中实现了条件呈现逻辑,否则e()将始终触发重新呈现
。请永远不要这样做,你不应该改变当前状态对象。
setState
不会立即重新渲染组件,但你已经立即更改了状态,这将导致很难找到bug!
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});