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

时间:2020-05-23 06:07:19

标签: javascript arrays reactjs object setstate

我正在开发闪存卡反应应用程序。我已将状态初始化为对象数组(用户一次最多只能添加10个术语/定义,因此限制为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循环运行时会增加),尤其是每个数组中term的属性目的。但是,出现编译失败错误。为什么此setState行不起作用?我的逻辑对我来说很有意义,但是我似乎缺少了一些东西……我的语法搞砸了吗?还是在设置对象数组的状态时缺少我所缺少的逻辑?谢谢你的想法。

4 个答案:

答案 0 :(得分:2)

您在这里:

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

引用来自您的 prev question

<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) ,
    });
}

答案 1 :(得分: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 });
}

答案 2 :(得分:1)

您的代码有几个问题:

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

这是一个有效的示例:code sandbox

答案 3 :(得分:0)

您在这里: 首先,您的输入应具有和id

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

秒,您的 onChange 函数应为:

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

第三,如果要许多术语输入,请不要重复使用相同名称的相同输入。还要在您的状态下更改您的输入名称,不要使自己陷入不明智的for循环中。