繁体   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