[英]Removing an object from array with splice() does not work as expected in React
我正在根据状态数组中的对象数量动态创建输入字段。 在每个字段旁边,我添加了一个按钮来删除该字段。 但是,当单击按钮时,它的行为出乎意料。
下面是视觉演示:
当我按“选项 0 ”上的“删除选项”按钮时:
输出是这样的:
但是,当我从console.log()
看到正确的对象被删除时。 这些是之前的console.log()
输出:
在上面的按钮点击后:
这是我如何从我的render()
的数组循环:
const questions = this.state.values_array.map((question, index) => {
return (
<div key = {question.question_id}>
{this.state.options_array.map((option, i) => (
option.questionID === question.question_id ? //to show only this question's options
<div>
<span>Option {i}:</span>
<TextField type="text" defaultValue={option.description} />
<span>Value:</span>
<TextField type="number" defaultValue={option.value}/>
<button onClick={() => this.removeOption(i)}>Remove Option</button>
</div>
:
null
))}
</div>
)
}
这是我用来删除输入字段的removeOption()
方法:
removeOption(index){
let options = [...this.state.options_array];
options.splice(index, 1);
this.setState({ options_array: options });
}
这是我在渲染返回中调用它的方式:
return (
<div>{questions}</div>
)
您缺少div
容器的键。 React 需要知道哪个 DOM 元素已被删除,以便重新渲染它。 另外,不要使用map
的index
作为键,而是使用类似 id 的东西,例如option.questionID
。
您需要从列表中过滤掉单个项目
removeOption(index) {
const options = this.state.options_array.filter((items, itemIndex) => itemIndex
!== index)
this.setState({ options_array: options });}
这种方法的缺陷在于,在 JavaScript 中,对象和数组都是引用类型,所以当我们得到一个数组时,我们实际上得到的是一个由 react 管理的原始数组对象的指针。 如果我们然后拼接它,我们已经改变了原始数据,虽然它可以正常工作而不会抛出错误,但这并不是我们应该这样做的方式,这可能导致不可预测的应用程序,绝对是一种不好的做法。 一个好的做法是在操作之前创建数组的副本,一个简单的方法是调用 slice 方法。 不带参数的切片只是复制完整数组并返回一个新数组,然后将其存储。 我们现在可以安全地编辑这个新数组,然后更新以使用我们的新数组来响应状态。 让我给你和例子:
我们有一个像const arr=[1,2,3,4,5]
这样的数组。 这是原始数组。
正如我之前告诉你的,我们可以这样做:
const newVar=arr.slice();
newVar.splice(Index,1);
console.log(newVar);
或者
这种方法的另一种选择是使用 ES6 特性,它是扩展运算符
我们之前的代码可以是这样的:
const newVar=[...arr]
newVar.splice(Index,1);
console.log(newVar);
就是这样。 祝你好运
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.