【问题标题】:How to set state to an array of objects in react如何在反应中将状态设置为对象数组
【发布时间】:2020-09-10 01:40:19
【问题描述】:

我正在开发一个闪存卡反应应用程序。我已将我的状态初始化为一个对象数组(用户一次最多只能添加 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 行不起作用?我的逻辑对我来说很有意义,但我似乎遗漏了一些东西......我的语法是否混乱?或者在为一组对象设置状态时,我是否缺少逻辑?感谢您的任何想法。

【问题讨论】:

    标签: javascript arrays reactjs object setstate


    【解决方案1】:

    给你:

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

    Ref 取自您的 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) ,
        });
    }
    

    【讨论】:

    • 啊,我还没有了解拼接。我也不知道事件和索引都可以通过。此信息非常有帮助。感谢您的帮助。
    • 我想知道是否可以将状态变量直接使用而不是作为参数传递给 onChange 函数被视为一种做法。是不是破坏了纯函数原理?
    • @AleksandrFomin,这里我们使用this.setState,它显示了基于类的组件,其中this 的使用非常普遍,在实践中也是如此,如果我们想专注于纯函数,那么我们可以使用功能性更强的基于功能的组件。
    【解决方案2】:

    在循环中更新你的状态是个坏主意,我建议你使用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 });
    }
    

    【讨论】:

    • 非常感谢!这很有帮助,我也非常感谢您提供了有关对象扩展运算符的资源。感谢您的帮助!
    • 很高兴为您提供帮助:)
    • 请注意,您可以在对象和数组上使用它,这里接受的答案使用它来创建新的数组段
    【解决方案3】:

    您的代码有几个问题:

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

    这是一个工作示例:code sandbox

    【讨论】:

      【解决方案4】:

      给你: 首先,你的输入应该有和 id

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

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

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

      第三,如果您想要多个词条输入,请不要使用相同的名称重复相同的输入。在您的状态下更改您的输入名称,不要将自己置于无意义的 for 循环中。

      【讨论】:

        猜你喜欢
        • 2019-01-10
        • 1970-01-01
        • 1970-01-01
        • 2019-06-20
        • 2019-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多