如何更新 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 钩子,我如何更新通过道具传递给孩子的对象?