Javascript 通过动态输入字段向对象数组添加值
我一直在关注一个YouTube教程,该教程介绍如何使用React动态添加或删除输入字段 本教程的大部分内容都很容易理解,我几乎实现了我想要做的事情,但是我在添加对象时遇到了一个问题,它会复制自身,而不是添加不同的值 代码如下:Javascript 通过动态输入字段向对象数组添加值,javascript,reactjs,Javascript,Reactjs,我一直在关注一个YouTube教程,该教程介绍如何使用React动态添加或删除输入字段 本教程的大部分内容都很容易理解,我几乎实现了我想要做的事情,但是我在添加对象时遇到了一个问题,它会复制自身,而不是添加不同的值 代码如下: import React, { useState } from "react"; import { Button, Form } from "react-bootstrap"; const countries = [
import React, { useState } from "react";
import { Button, Form } from "react-bootstrap";
const countries = [
{
key: "1",
name: "",
value: ""
},
{
key: "2",
name: "Afghanistan",
value: "Afghanistan"
},
{
key: "3",
name: "Albania",
value: "Albania"
},
{
key: "4",
name: "Algeria",
value: "Algeria"
},
{
key: "5",
name: "Angola",
value: "Angola"
},
{
key: "6",
name: "Argentina",
value: "Argentina"
},
]
const listanswers = [
{
key: '01',
name: '',
value: '',
},
{
key: '02',
name: 'Yes',
value: 'Yes',
},
{
key: '03',
name: 'No',
value: 'No',
},
{
key: '04',
name: 'Unsure',
value: 'Unsure',
},
];
export default function Section1_3() {
const [question1_7, setQuestion1_7] = useState("");
const [instance1_7, setInstance1_7] = useState([
{
Country: "",
Answer: "",
}
]);
// handle input change
const handleInputChange = (instance, setinstance, e, index) => {
const { name, value } = e.target;
const list = [...instance];
list[index][name] = value;
setinstance(list);
};
// handle click event of the Remove button
const handlRemoveInstance = (instance, setinstance, index) => {
const list = [...instance];
list.splice(index, 1);
setinstance(list);
};
// handle click event of the Add button
const handleAddInstance = (instance, setinstance) => {
setinstance([...instance, instance[0]]);
};
return (
<div>
<Form>
<Form.Group size="lg" controlId="formSection3">
{instance1_7.map((answer, i) => {
return (
<div key={(i + 1) * 3}>
<Form.Label>Instance variable 1</Form.Label>
{console.log(answer)}
<Form.Control
name="Country"
as="select"
onChange={e =>
handleInputChange(instance1_7, setInstance1_7, e, i)
}
>
{countries.map(country => (
<option
key={country.key}
value={country.value}
label={country.name}
/>
))}
</Form.Control>
<Form.Label>Instance variable 2</Form.Label>
<Form.Control
name="Answer"
as="select"
onChange={e =>
handleInputChange(instance1_7, setInstance1_7, e, i)
}
>
{listanswers.map(answer => (
<>
<option
key={answer.key}
value={answer.value}
label={answer.name}
/>
</>
))}
</Form.Control>
{instance1_7.length !== 1 && (
<Button
variant="danger"
onClick={() =>
handlRemoveInstance(instance1_7, setInstance1_7, i)
}
>
Remove
</Button>
)}
{instance1_7.length - 1 === i && (
<Button
variant="success"
onClick={() =>
handleAddInstance(instance1_7, setInstance1_7, i)
}
>
Add
</Button>
)}
</div>
);
})}
</Form.Group>
</Form>
<div style={{ marginTop: 20 }}>{JSON.stringify(instance1_7)}</div>
</div>
);
}
更新:我刚意识到您发布了解决方案:o) 下面是对问题的解释 请看一下第86行的代码好吗
// handle click event of the Add button
const handleAddInstance = (instance, setinstance) => {
setinstance([...instance, instance[0]]);
};
您将看到在实例[0]
上有一个复制操作。在javascript中,当您将对象作为副本传递时,该对象将作为引用传递。更改新添加对象上的值后,它也将更新其他引用上的值
如果要复制,则需要创建克隆
有多种方法可以做到这一点。例如,您可以使用JSON API删除引用:
JSON.parse(JSON.stringify(instance[0]))
这比:
Object.assign({}, instance[0])
基准:
仔细查看对象.assign()
:
或者,您可能需要由
lodash
提供的名为cloneDeep
的函数,并按以下方式导入:
import cloneDeep from 'lodash/cloneDeep';
然后:
setinstance([...instance, cloneDeep(instance[0]]));
最后,;我建议使用本机赋值方法Object.assign({},实例[0])
祝你好运:o)请编辑问题并添加答案?非现场代码的链接必须附有问题代码。谢谢你提供的链接,我确实没有把整个帖子做得像它应该做的那样。不管怎样,我还是能成功的…我真蠢!感谢您花时间提供这么好的解释,您使用Object.assign提供的解决方案正是我目前需要的,以便使我的代码更干净:)不客气,很高兴它能帮助我:o)
setinstance([...instance, cloneDeep(instance[0]]));
// handle click event of the Add button
const handleAddInstance = (instance, setinstance) => {
setinstance([...instance, Object.assign({}, instance[0])]);
};