为了账号安全,请及时绑定邮箱和手机立即绑定

在React中使用setState更新对象

/ 猿问

在React中使用setState更新对象

暮色呼如 2019-10-23 14:20:53

是否可以使用setState更新对象的属性?


就像是:


this.state = {

   jasper: { name: 'jasper', age: 28 },

}

我努力了:


this.setState({jasper.name: 'someOtherName'});

和这个:


this.setState({jasper: {name: 'someothername'}})

第一个导致语法错误,第二个则什么都不做。有任何想法吗?


查看完整描述

3 回答

?
吃鸡游戏

有多种方法可以执行此操作,因为状态更新是异步操作,因此要更新状态对象,我们需要使用带有updater函数setState。


1-最简单的一个:


首先创建的副本,jasper然后执行以下更改:


this.setState(prevState => {

  let jasper = Object.assign({}, prevState.jasper);  // creating copy of state variable jasper

  jasper.name = 'someothername';                     // update the name property, assign a new value                 

  return { jasper };                                 // return new object jasper object

})

除了使用,Object.assign我们还可以这样写:


let jasper = { ...prevState.jasper };

2-使用扩展运算符:


this.setState(prevState => ({

    jasper: {                   // object that we want to update

        ...prevState.jasper,    // keep all other key-value pairs

        name: 'something'       // update the value of specific key

    }

}))

注意: Object.assign并且Spread Operator仅创建浅表副本,因此,如果您定义了嵌套对象或对象数组,则需要使用其他方法。


更新嵌套状态对象:

假设您将状态定义为:


this.state = {

  food: {

    sandwich: {

      capsicum: true,

      crackers: true,

      mayonnaise: true

    },

    pizza: {

      jalapeno: true,

      extraCheese: false

    }

  }

}

要更新披萨对象的ExtraCheese:


this.setState(prevState => ({

  food: {

    ...prevState.food,           // copy all other key-value pairs of food object

    pizza: {                     // specific object of food object

      ...prevState.food.pizza,   // copy all pizza key-value pairs

      extraCheese: true          // update value of specific key

    }

  }

}))

更新对象数组:

假设您有一个待办事项应用程序,并且您正在以这种形式管理数据:


this.state = {

  todoItems: [

    {

      name: 'Learn React Basics',

      status: 'pending'

    }, {

      name: 'Check Codebase',

      status: 'pending'

    }

  ]

}

要更新任何待办事项对象的状态,请在数组上运行一个映射并检查每个对象的某些唯一值,如果为condition=true,则返回具有更新值的新对象,否则返回相同的对象。


let key = 2;

this.setState(prevState => ({


  todoItems: prevState.todoItems.map(

    el => el.key === key? { ...el, status: 'done' }: el

  )


}))

建议:如果对象没有唯一值,则使用数组索引。


查看完整回答
反对 回复 2019-10-23
?
蝴蝶不菲

这是最快,最易读的方式:


this.setState({...this.state.jasper, name: 'someothername'});

即使this.state.jasper已经包含name属性,name: 'someothername'也要使用新名称。


查看完整回答
反对 回复 2019-10-23
?
qq_花开花谢_0

我用了这个解决方案。


如果您有这样的嵌套状态:


this.state = {

  formInputs:{

    friendName:{

      value:'',

      isValid:false,

      errorMsg:''

    },

    friendEmail:{

      value:'',

      isValid:false,

      errorMsg:''

    }

  }

}

您可以声明handleChange函数,该函数复制当前状态并使用更改后的值重新分配它


handleChange(el) {

    let inputName = el.target.name;

    let inputValue = el.target.value;


    let statusCopy = Object.assign({}, this.state);

    statusCopy.formInputs[inputName].value = inputValue;


    this.setState(statusCopy);

  }

这里是带有事件监听器的html。确保使用与状态对象相同的名称(在本例中为“ friendName”)


<input type="text" onChange={this.handleChange} " name="friendName" />


查看完整回答
反对 回复 2019-10-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信