是否有可能更新对象的属性与setState?

喜欢的东西:

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

我试过:

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

这:

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

第一个会导致语法错误,第二个则什么都不做。什么好主意吗?


当前回答

你可以试试这个:

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

其他回答

不使用异步和等待使用此…

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

如果你使用异步和等待使用这个…

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

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

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

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

这个设置对我来说很管用:

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

this.setState({newState: newState});

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

你的第二种方法不起作用,因为{name: 'someothername'}等于{name: 'someothername',年龄:undefined},所以undefined会覆盖原始的年龄值。

当涉及到改变嵌套对象的状态时,一个很好的方法是Immutable.js

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

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

使用钩子,我们可以做到以下方式

const [student, setStudent] = React.useState({name: 'jasper', age: 28});
 setStudent((prevState) => ({
          ...prevState,
          name: 'newName',
        }));