如何更新 React 组件的数组?

Posted

技术标签:

【中文标题】如何更新 React 组件的数组?【英文标题】:How do I update an array for a React component? 【发布时间】:2015-07-22 13:57:07 【问题描述】:

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

例如,我有一个 _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 组件数组数据的正确方法吗?还是我错过了什么?

【问题讨论】:

也许不同的方法更适合不变性范式。例如。将所选人员对象的引用存储在组件的另一个属性中,而不是改变人员对象。 为什么不在出现新选择时触发更新? React 不跟踪对象的属性,因此仅设置选定对象是行不通的。例如,您可以拨打forceUpdate 对不起,我发现在上下文中遵循您的代码 sn-ps 有点困难,但我认为您应该将选定的人存储在组件状态(或其父级的状态,具体取决于哪个组件selectPerson 在中实现)并通过调用 this.setState(_suggestedPeople: people, selectedPerson: person) 强制重新渲染。在这个问题的答案中有一个小提琴jsfiddle.net/map5vf94/11,这可能是你想要做的-***.com/questions/30042657/… 谢谢。起初我确实使用了forceUpdate,但我觉得我不应该这样做,而是我正在规避一个潜在的问题。也许事实并非如此。对于这个问题,我需要跟踪多个选择。你会提倡第二个名单吗? selectedPeople 数组而不是 selectedPerson 对象? 【参考方案1】:

您似乎没有使用 React 的内置状态管理。如果你这样做,你的两种更新状态的方法之间的中间立场将起作用。当组件的状态或属性发生变化时,组件将重新渲染。

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

通过实现来初始化组件状态

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

【讨论】:

这不会做任何事情......在这件事中修改对象不会触发状态更改。您必须替换整个数组元素。 @tomitrescak 它工作得很好,因为对setState 的调用会强制渲染。来自文档:setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate(). 请永远不要这样做,你不应该改变当前状态对象。 setState 不会立即重新渲染您的组件,但您已经立即更改了状态,这将导致很难找到错误!【参考方案2】:

我认为你做错了。你可能会从 Angular js 做出反应。不要使用函数,要操作对象,请使用 useState。组件内的本地状态。

示例:

const Comp = () => 
  const [selectedPerson, setSelectedPerson] = useState();
  function onSelect(personID, selected) 
    var person = _.find(_suggestedPeople,  id: personID );
    if (person) 
      person.selected = selected;
    
    setSelectedPerson(person);
  
  return (
    <div>
      selectedPerson.name
      <select>
        <option onSelect=() => onSelect(id, "ssjsjs")></option>
      </select>
    </div>
  );
;

【讨论】:

以上是关于如何更新 React 组件的数组?的主要内容,如果未能解决你的问题,请参考以下文章

使用 React 钩子,我如何更新通过道具传递给孩子的对象?

React Js使用onChange将数组内的值更新到子组件

React Context 组件在状态更改时不会更新

如何从 React 中的子组件更新父组件(功能)

如何测试 React 组件的 prop 更新

React 功能组件 - 当组件返回元素数组时,如何将 refs 传递回父级?