簡體   English   中英

如何使用復選框更新 useState 中的數組

[英]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 的新鍵。 您需要做的是傳播datepurchase_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM