在循环中调用SetState时如何合并对象

问题描述

在我的组件中,我的状态看起来像这样:

  class MainClass 

  constructor(props) {
    super(props);
    this.state = {
      form: {
        startDate:"1/11/2020",endDate:"5/11/2020",....
     },};
  }

我有一个可以同时更新开始日期和结束日期的功能,另一个可以更新表格的功能

  handleFormChanges = targets => {
    targets.forEach(function (target) {
      this.setState({
        form: { ...this.state.form,[target.name]: target.value },});     
     });
  };
  

..... 


updateDate(startDate,endDate) {
const newStartDate = {name:"startDate",value:startDate.value}
const newEndDate = {name:"endDate",value:endDate.value}
this.handleFormChanges([newStartDate,newEndDate])
}  

因此,我意识到在循环中调用setState是一种代码味道,而不是反应的工作方式。如何合并目标数组,以便只需要调用一次setState?

解决方法

您可以使用reduce一次性累积targets

编辑:要同时使用单个对象和对象数组,可以将targets放在方括号[]中,然后将flat()包裹

this.setState({
  form: {
    ...this.state.form,...[targets].flat().reduce(
      (acc,target) => ({ ...acc,[target.name]: target.value }),{}
    ),},})

,

你可以有类似的东西

const newObj={};
 targets.forEach(function (target) {
 
        newObj[target.name]=target.value,});
this.setState({...this.state.form,...newObj})

,

这绝对是一个错误的主意,因为您可能会丢失一些数据并导致每次迭代的额外渲染。

每个功能一次使用setState的主要思想。另外,您不需要使用handleFormChanges,更好地通过键添加值)


updateDate(startDate,endDate) {

 this.setState({
        form: { 
        ...this.state.form,"startDate": startDate.value,endDate: endDate.value
          },});    
}