[英]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.