无法在 React 状态下设置对象数组

Posted

技术标签:

【中文标题】无法在 React 状态下设置对象数组【英文标题】:Trouble setting array of object in React state 【发布时间】:2020-09-11 12:26:43 【问题描述】:

我很困。我正在构建一个反应闪存卡应用程序,并且在状态是一组对象时询问了几个关于设置状态的问题。我一直在玩并研究不同的解决方案,我似乎非常接近,但我似乎无法让这段代码正常工作。这是我的组件:

import React,  Component  from 'react'

export class TermForm extends Component 
    state =  
        allTerms: [
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        ,
        
            term: '',
            def: ''
        
    ]

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

    onChangeDef = (e, index) => 
        e.preventDefault();
        this.setState(
            allTerms : [
            ...this.state.allTerms.splice(0,index) ,
            
                ...this.state.allTerms[index],
                def: e.target.value
            ,
            ...this.state.allTerms.splice(index+1)
            ]
        )
    

    render() 
        return (
            this.props.numberOfTerms.map((index) => (
                <div key=index>
                    <input type="text" placeholder="TERM" value=this.state.allTerms.term onChange=(event) => this.onChangeTerm(event, index)></input>
                    <input type="text" placeholder="DEFINITION" value=this.state.allTerms.def onChange=(e) => this.onChangeDef(e, index)></input>
                </div>
            ))
        )
    


export default TermForm

对于上下文,我的渲染方法中的 return 语句正在返回一个动态表单。基本上,根据用户想要添加的术语数量,呈现的表单可以有 1 到 10 行(每行包含用户想要添加的术语的输入字段和定义的另一个输入字段)。我对术语和定义有单独的 onChange 事件。当我为第一个术语设置状态时(因此通过 onChangeTerm 和 onChangeDef 函数),状态设置得很好。然而,对于在第一张之后尝试创建的任意数量的卡片,状态都会变得一团糟。通过查看 chrome 的反应工具中的状态,我可以看到在尝试创建第二张卡片(以及第一张卡片之后的任意数量的卡片)之后,该术语已设置,但是当我输入定义时,它会清除该术语价值。老实说,我很困惑。我认为问题出在我的一个或两个 onChange 函数中,但我似乎无法弄清楚问题是什么。任何帮助都将不胜感激。

【问题讨论】:

numberOfTerms 是什么,一个仅用于指定计数的数组? 正确。该道具包含用户想要添加的术语数。它只是一个数组,其元素数量与用户想要添加的术语数量相同。 所以是数字还是数组? ;-) 它是一个数字数组。例如,如果用户想要添加 4 个术语,则数组将如下所示:[0, 1, 2, 3]。我创建这个数组的目的是为了让我可以在这个数组上运行 map 函数。该数组始终包含与用户想要创建的术语数量相同数量的元素。 【参考方案1】:

我建议将数组存储在父组件中,并使用TermForm 组件单独显示每个术语+定义。然后,当您更新一个术语/定义时,它会设置新状态并将信息传播给父级:https://codesandbox.io/s/pensive-morning-95cmx

我还渲染应用程序状态以显示它可以工作;)还可以改进allTerms 数组的创建。例如用循环填充它

// App.js
import React,  Component  from "react";
import "./styles.css";
import  TermForm  from "./TermForm";

export default class App extends Component 
  state = 
    allTerms: [
      
        term: "",
        def: ""
      ,
      
        term: "",
        def: ""
      ,
      
        term: "",
        def: ""
      ,
      
        term: "",
        def: ""
      ,
      
        term: "",
        def: ""
      
    ]
  ;
  updateTermDef = (term, def, idx) => 
    const newTerms = [...this.state.allTerms];
    newTerms[idx] = 
      term,
      def
    ;
    this.setState( allTerms: newTerms );
  ;
  render() 
    return (
      <div className="App">
        this.state.allTerms.map((termDef, idx) => (
          <TermForm
            term=termDef.term
            def=termDef.def
            idx=idx
            updateTermDef=(term, def) => this.updateTermDef(term, def, idx)
          />
        ))
        <h1>App state: </h1>
        this.state.allTerms.map(termDef => (
          <>
            <span>
              termDef.term : termDef.def
            </span>
            <br />
          </>
        ))
      </div>
    );
  

//TermForm.js

import React,  Component  from "react";

export class TermForm extends Component 
  state = 
    term: this.props.term,
    def: this.props.def
  ;

  render() 
    return (
      <div key=this.props.idx>
        <input
          type="text"
          placeholder="TERM"
          value=this.state.term
          onChange=event =>
            this.setState(
               term: event.currentTarget.value ,
              this.props.updateTermDef(this.state.term, this.state.def)
            )
          
        />
        <input
          type="text"
          placeholder="DEFINITION"
          value=this.state.def
          onChange=event =>
            this.setState(
               def: event.currentTarget.value ,
              this.props.updateTermDef(this.state.term, this.state.def)
            )
          
        />
      </div>
    );
  

【讨论】:

以上是关于无法在 React 状态下设置对象数组的主要内容,如果未能解决你的问题,请参考以下文章

REACT 如何在 setState 中存储对象而不是对象数组?

React - 使用 setState 更新状态中的对象数组

如何映射一组对象,删除一个并将我的状态设置为 react-native 中的新数组?

无法访问 JavaScript 对象数组 (React.js) 中的属性

React - 使用setState更新状态中的对象数组

如何在不删除旧状态的情况下设置对象的状态数组