在React中使用setState更新对象

时间:2017-04-26 15:47:09

标签: reactjs state

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

类似的东西:

this.state = {
   jasper: { name: 'jasper', age: 28 },
}

我试过了:

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

和此:

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

第一个是语法错误,第二个什么都不做。有什么想法吗?

20 个答案:

答案 0 :(得分:308)

有多种方法可以做到这一点。

1-最简单的一个:

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

let jasper = Object.assign({}, this.state.jasper);    //creating copy of object
jasper.name = 'someothername';                        //updating value
this.setState({jasper});

我们也可以像这样编写它来代替使用Object.assign

let jasper = {...this.state.jasper};

2-使用spread operator

this.setState(prevState => ({
    jasper: {
        ...prevState.jasper,
        name: 'something'
    }
}))

答案 1 :(得分:19)

最快且最易读的方式:

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

Althought this.state.jasper已包含名称属性,后者name: 'someothername'已被使用。

答案 2 :(得分:15)

在这里使用spread运算符和一些ES6

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

答案 3 :(得分:6)

我使用了这个解决方案。

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

   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" />

答案 4 :(得分:5)

尝试一下,它应该可以正常工作

this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));

答案 5 :(得分:3)

第一种情况确实是语法错误。

由于我无法看到您组件的其余部分,因此很难理解为什么您在此处将状态中的对象嵌套。将对象嵌套在组件状态中不是一个好主意。尝试将初始状态设置为:

this.state = {
  name: 'jasper',
  age: 28
}

这样,如果你想更新名字,你可以打电话:

this.setState({
  name: 'Sean'
});

这会实现你的目标吗?

对于更大,更复杂的数据存储,我会使用像Redux这样的东西。但那要先进得多。

组件状态的一般规则是仅使用它来管理组件的UI状态(例如,活动,计时器等)

查看以下参考资料:

答案 6 :(得分:2)

我知道这里有很多答案,但是令我惊讶的是,没有一个在setState之外创建新对象的副本,然后只是setState({newObject})。干净,简洁,可靠。因此,在这种情况下:

const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(prevState => ({ jasper }))

或者对于动态属性(对于表单非常有用)

const jasper = { ...this.state.jasper, [VarRepresentingPropertyName]: 'new value' }
this.setState(prevState => ({ jasper }))

答案 7 :(得分:1)

enter image description here

   this.state = {
      objName: {
        propertyOne: "",
        propertyTwo: ""
      }
    };

enter image description here

this.setState(prevState => ({
  objName: {
    ...prevState.objName,
    propertyOne: "Updated Value",
    propertyTwo: "Updated value"
  }
}));

答案 8 :(得分:1)

试试这个:

const { jasper } = this.state; //Gets the object from state
jasper.name = 'A new name'; //do whatever you want with the object
this.setState({jasper}); //Replace the object in state

答案 9 :(得分:0)

通过使用 input html input name 属性,我们可以采用更动态的方法来更新对象属性。

DOM html input name attribute

<input type="text" name="fname" handleChange={(e: any) => { updatePerson(e) }}/>
<input type="text" name="lname" handleChange={(e: any) => { updatePerson(e) }}/>

React / TSX object.assign

const [person, setPerson] = useState<IPerson>({});

   function updatePerson(e: React.ChangeEvent<HTMLInputElement>): void {
        const { name, value } = e.currentTarget;

        setPerson(prevState => {
            const newState = Object.assign(person, { [name]: value })
            return { ...prevState, ...newState };
        });
    }

答案 10 :(得分:0)

如果更新一个键为字符串的对象

例如假设您的状态对象是

serviceDays: {
    Sunday: true,
    Monday: true,
    Tuesday: false,
    Wednesday: true,
    Thurday: false,
    Friday: true,
    Saturday: true
  }

所以你可以通过以下方式更新

const onDayClick = day => {
  const { serviceDays } = this.state
  this.setState(prevState => ({
    serviceDays: {
      ...prevState.serviceDays,
      [day]: serviceDays[day] ? false : true
    }
  }))
}

答案 11 :(得分:0)

您的第二种方法不起作用,因为{name: 'someothername'}等于{name: 'someothername', age: undefined},因此undefined将覆盖原始年龄值。

当要更改嵌套对象的状态时,最好的方法是Immutable.js

this.state = {
  jasper: Record({name: 'jasper', age: 28})
}

const {jasper} = this.state
this.setState({jasper: jasper.set(name, 'someothername')})

答案 12 :(得分:0)

此设置对我有用:

let newState = this.state.jasper;
newState.name = 'someOtherName';

this.setState({newState: newState});

console.log(this.state.jasper.name); //someOtherName

答案 13 :(得分:0)

这是使用immer immutabe实用程序的另一种解决方案,非常适合轻松嵌套的深层对象,您无需担心突变

this.setState(
    produce(draft => {
       draft.jasper.name = 'someothername
    })
)

答案 14 :(得分:0)

不使用Async和Await使用此...

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

如果您将Async和Await一起使用,请使用此...

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

答案 15 :(得分:0)

简单而动态的方式。

这可以完成工作,但是您需要将所有id都设置为父对象,这样父对象将指向对象的名称,即id =“ jasper”,并在其中命名输入元素=属性的名称。碧玉。

 throws.push(throws.front());
 throws.pop();

答案 16 :(得分:0)

您可以尝试以下操作:  (注意:输入标签的名称===对象的字段)

<input name="myField" type="text" 
      value={this.state.myObject.myField} 
     onChange={this.handleChangeInpForm}></input>

-----------------------------------------------------------
handleChangeInpForm = (e) => {
   let newObject = this.state.myObject;
   newObject[e.target.name] = e.target.value;
   this.setState({
     myObject: newObject 
   })
}

答案 17 :(得分:0)

此外,如果您不想复制所有“状态”对象,则遵循Alberto Piras解决方案:

handleChange(el) {
    let inputName = el.target.name;
    let inputValue = el.target.value;

    let jasperCopy = Object.assign({}, this.state.jasper);
    jasperCopy[inputName].name = inputValue;

    this.setState({jasper: jasperCopy});
  }

答案 18 :(得分:0)

另一种选择:从 Jasper 对象中定义变量,然后调用变量。

点差操作员:ES6

this.state = {  jasper: { name: 'jasper', age: 28 } } 

let foo = "something that needs to be saved into state" 

this.setState(prevState => ({
    jasper: {
        ...jasper.entity,
        foo
    }
})

答案 19 :(得分:-1)

您可以尝试以下操作:

this.setState(prevState => {
   prevState = JSON.parse(JSON.stringify(this.state.jasper));
   prevState.name = 'someOtherName';
   return {jasper: prevState}
})

或其他财产:

this.setState(prevState => {
   prevState = JSON.parse(JSON.stringify(this.state.jasper));
   prevState.age = 'someOtherAge';
   return {jasper: prevState}
})

或者您可以使用handleChage函数:

handleChage(event) {
   const {name, value} = event.target;
    this.setState(prevState => {
       prevState = JSON.parse(JSON.stringify(this.state.jasper));
       prevState[name] = value;
       return {jasper: prevState}
    })
}

和HTML代码:

<input 
   type={"text"} 
   name={"name"} 
   value={this.state.jasper.name} 
   onChange={this.handleChange}
/>
<br/>
<input 
   type={"text"} 
   name={"age"} 
   value={this.state.jasper.age} 
   onChange={this.handleChange}
/>