[英]How to update an array inside a useState with a checkbox
我正在尝试创建一个表单,其中将检查的每个项目从 useState-product[] 中推送或删除。
我的意思是:
请求后会自动生成一个锤子表。
<table>
<thead>
<tr>
<th scope="col">Use</th>
<th scope="col">ID</th>
<th scope="col">Length</th>
<th scope="col">Width</th>
<th scope="col">Weight</th>
</tr>
</thead>
<tbody>
{response &&
response.map((element) => (
<tr key={element._id}>
<th>
<input type="checkbox" value={element._id} />
</th>
<th>{element._id}</th>
<th>{element.length}</th>
<th>{element.width}</th>
<th>{element.weight}</th>
</tr>
))}
</tbody>
</table>
此表是将与其他信息(包括锤子数组)一起发送的表单的一部分,我将所有此表单数据保存在以下 useState 中。
interface Order {
date: Date,
hammers: string[],
purchase_order: number,
}
const [form, setForm] = useState <Order> ({
date: new Date(),
hammers: [],
purchase_order: 0
});
我以这种方式更新日期和购买订单:
const handleForm = (e: React.ChangeEvent<HTMLInputElement>) => {
setForm({ ...form, [e.target.id]: e.target.value });
};
所以我的问题是,每次从表中选中或取消选中锤子时,如何使用 _id 更新锤子数组?
示例 hammers[ ]:如果选中 2
锤子 = ["639761fff0bbbac77d77e44d", "6397af36a3ead940becb8805"]
您必须解决两个问题。 第一个是正确设置事件,第二个是正确更新数组。
当我们查看您的事件处理程序时:
const handleForm = (e: React.ChangeEvent<HTMLInputElement>) => {
setForm({ ...form, [e.target.id]: e.target.value });
};
我们看到您正在寻找 ID ( e.target.id
),但查看您的输入:
<input type="checkbox" value={element._id} />
找不到id
属性。 当检查输入或未选中输入时,此功能也无法发射。 所以让我们先解决这两个问题:
<input
id={element._id}
type="checkbox"
onChange={handleForm}
/>
您会注意到我没有费心向输入添加value
,因此这是一个不受控制的输入。
现在您的 HTML (JSX) 是正确的,我们可以查看事件处理程序本身。 您的初始状态如下所示:
const [form, setForm] = useState <Order> ({
date: new Date(),
hammers: [],
purchase_order: 0
});
所以你需要让你的函数返回一个相似的形状,否则一旦你开始选中一些框,你的状态就会变得一团糟。 您当前的代码传播现有的状态对象,然后添加一个带有复选框 ID 的新键。 您需要做的是传播date
和purchase_order
值(或者更新它们,如果合适的话——您告诉我),然后操纵hammers
值。
此外,复选框的value
只是字符串'on'
。 您应该改用event.target.checked
。
所以:
const handleForm = (e: React.ChangeEvent<HTMLInputElement>) => {
const {checked, id} = event.target;
const {hammers} = form;
const copyOfHammers = [...hammers];
if (checked) {
// add a new id to the array
copyOfHammers.push(id);
} else {
// remove the id from the array
copyOfHammers.splice(copyOfHammers.indexOf(id), 1);
}
return {
...form,
hammers: copyOfHammers,
};
};
这是示例代码,但您可以根据需要对其进行修改。 这也不是可能从数组中添加或删除项目的唯一方法。
您需要做的是检查 e.target.value 是真还是假,并从数组中添加或删除 elementId。 我建议 handleForm 像这样:
const handleForm = (e: React.ChangeEvent<HTMLInputElement>, elementId) => {
setForm(form => {
let newFormState = form
if (event.target.checked) {
newFormState.hammers = [...form.hammers, elementId]
} else {
newFormState.hammers = form.hammers.filter(f => f !== elementId)
}
return newFormState
};
所以基本上我们正在创建您的表单的副本,根据 event.target.checked 覆盖您的 form.hammers 状态,并将 newState 返回给您的 reducer。
我喜欢使用 setForm 作为回调函数,就像我们在这里所做的那样,这意味着不是给出新状态,而是说“嘿......给我当前状态(在本例中为“form”,并将其作为回调(由箭头函数)我想返回给你新的状态。
这可以用更少的代码行来完成,但为了清楚起见,我以一种更说教的方式完成了它。
现在......输入应该收到
<input onClick={(e) => handleForm(e, element._id)} ...and our other props />
因为我们将 element._id 传递给函数。
干杯。
const handleChecked = id => e => {
if(e.target.checked){
setForm({ ...form, hammers: [...form.hammers, id] })
} else{
setForm({ ...form, hammers: form.hammers.filter(e => e !== id) })
}};
这应该可以通过一些调整来完成
const handleForm = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.checked) {
setForm({ ...form, hammers: [...form.hammers, e.target.value] });
} else {
setForm({
...form, hammers: form.hammers.filter((element) => element !== e.target.value),
});
}
};
和复选框
onChange={handleForm}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.