如何在反应中将状态设置为对象数组

How to set state to an array of objects in react

我正在开发闪存卡 React 应用程序。我已将状态初始化为对象数组(用户一次最多只能添加 10 terms/definitions,因此限制为 10),如下所示:

state = { 
        allTerms: [
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        },
        {
            term: '',
            def: ''
        }
    ]
}

输入来自一个动态表单,该表单根据用户想要添加的卡片数量提供 X 个输入字段。我当前的问题是我的 onChange 函数。当用户在输入字段中键入内容时(现在专注于术语和数字,我可以使用类似的解决方案来定义)更改会调用我的 onChangeTerm 函数,其中我有一个 for 循环:

onChangeTerm = (event) => {

        for(var i = 0; i < this.props.numberOfTerms.length; i++) {
            this.setState({ allTerms[i].term: event.target.value});
        }
    }

我在使用 setState 行时遇到了问题。我的想法是 allTerms 是我处于状态的数组。我想将事件(用户输入)的值设置为数组的 i 元素(在用户想要添加多张卡片的情况下随着 for 循环运行而增加),特别是 属性每个对象中的术语。但是,我得到一个编译失败的错误。为什么这个 setState 行不起作用?我的逻辑对我来说很有意义,但我似乎遗漏了一些东西......我的语法搞砸了吗?或者在为对象数组设置状态时是否缺少我所缺少的逻辑?感谢您的任何想法。

给你:

您可以将事件和索引都传递给函数:

参考取自您的 :

<input type="text" name={i.term} placeholder="TERM" 
value={this.state.allTerms[i].term} 
onChange={(e) =>this.onChange(e,i)}> // <--- Change
</input>

更新如下:

onChangeTerm = (event , index) => {
    this.setState({
        allTerms : [
        ...this.state.allTerms.splice(0,index) ,
        {
            ...this.state.allTerms[index],
            term: event.target.value
        },
        ...this.state.allTerms.splice(index+1) ,
    });
}

在循环内更新状态是个坏主意,我建议您使用 object spread operator,一旦完成状态对象的构建,就将其分配给组件状态:

onChangeTerm = (event) => {
  let allTerms = {}
  for(var i = 0; i < this.props.numberOfTerms.length; i++) {
    allTerms = { ...this.state.allTerms[i], term: event.target.value }
  }
  this.setState({ allTerms });
}

给你: 首先,您的输入应包含 id

<input type="text" id = 'term'/>

其次,您的 onChange 函数应该是:

onChangeTerm = (e) =>  {
e.preventDefault();
 this.setState({ [e.target.id]: e.target.value}); 
 }

第三,如果你想要多个术语输入,那么不要用相同的名称重复相同的输入。在您的状态下也更改您的输入名称,不要让自己陷入不明智的 for 循环。

您的代码有几个问题:

  • 在循环中更新状态不是一个好主意 -> 可能会导致性能不佳,因为它会经常渲染
  • setState的第一个参数是一个对象({key: value}),如果你想使用动态键你必须做{[dynamicKey]: value}
  • 状态对象是重复的,我会动态构建它

这是一个工作示例:code sandbox