无法在 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 中的新数组?