我试图通过使用这样的嵌套属性来组织我的状态:

this.state = {
   someProperty: {
      flag:true
   }
}

但是像这样更新状态,

this.setState({ someProperty.flag: false });

是行不通的。怎样才能正确地做到这一点呢?


当前回答

这是第一个答案的变体,不需要任何额外的包、库或特殊函数。

state = {
  someProperty: {
    flag: 'string'
  }
}

handleChange = (value) => {
  const newState = {...this.state.someProperty, flag: value}
  this.setState({ someProperty: newState })
}

为了设置特定嵌套字段的状态,您已经设置了整个对象。为此,我创建了一个变量newState,并首先使用ES2015扩展操作符将当前状态的内容扩散到该变量中。然后,我用新值替换了this.state.flag的值(因为我在将当前状态扩展到对象后设置了flag: value,所以当前状态下的flag字段将被覆盖)。然后,我简单地将someProperty的状态设置为newState对象。

其他回答

如果你想动态设置状态


下面的示例动态设置表单的状态,其中状态中的每个键都是object

 onChange(e:React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
    this.setState({ [e.target.name]: { ...this.state[e.target.name], value: e.target.value } });
  }

我用了这个方法。

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

   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

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

我发现这对我很有用,在我的案例中有一个项目表单,例如,你有一个id和一个名称,我宁愿为一个嵌套的项目维护状态。

return (
  <div>
      <h2>Project Details</h2>
      <form>
        <Input label="ID" group type="number" value={this.state.project.id} onChange={(event) => this.setState({ project: {...this.state.project, id: event.target.value}})} />
        <Input label="Name" group type="text" value={this.state.project.name} onChange={(event) => this.setState({ project: {...this.state.project, name: event.target.value}})} />
      </form> 
  </div>
)

让我知道!

根据框架的标准,不确定这在技术上是否正确,但有时您只是需要更新嵌套对象。这是我使用钩子的解决方案。

setInputState ({ ... inputState, [括号]:内务部[括号],[childKey]: });

我们使用Immer https://github.com/mweststrate/immer来处理这类问题。

只是在我们的一个组件中替换了这段代码

this.setState(prevState => ({
   ...prevState,
        preferences: {
            ...prevState.preferences,
            [key]: newValue
        }
}));

用这个

import produce from 'immer';

this.setState(produce(draft => {
    draft.preferences[key] = newValue;
}));

使用immer,您可以将您的状态作为“普通对象”处理。 神奇的事情发生在代理对象的幕后。