简体   繁体   English

从对象数组中动态删除项目

[英]Remove Items dynamically from Array of Objects

How do I remove an object from an array dynamically after clicking the "remove" button.单击“删除”按钮后,如何从数组中动态删除 object。

For example, in the below code the table has n rows.例如,在下面的代码中,表格有 n 行。 After clicking on a particular remove button, it should delete only that row.单击特定的删除按钮后,它应该只删除该行。 Just like a todo list.就像一个待办事项列表。

But in my case entire table is getting deleted.但在我的情况下,整个表都被删除了。

const [items,itemList]=useState([]);
 const [companyName,setCompanyName]=useState('');
 const [experience, setExperience]=useState();


//Adding Items to Array after clicking "Add" button
const handleClose=()=>{
        itemList((old)=>{
            return [...old,{companyName,experience}]
          })
         
    }
//Removing Items from Array After clicking Remove button
const removeItem=(index)=>{
         
        itemList((old)=>{
          return old.filter((arrEle,i)=>{
            return (
               
                i!==index
                );
          })
        })
   }

//Displaying Array of objects on UI
<Table  striped bordered hover size="sm">
                                <thead>
                                    <tr>
                                        
                                        <th>Company Name</th>
                                        <th>Experience</th>
                                        <th>Actions</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    
                                        {
                                            items.map((item,index)=>{

                                                return(
                                                    <tr>
                                                    <td>{item.companyName}</td>
                                                    <td>{item.experience}</td>
                                                    <td><button onClick={()=>{removeItem(index)}}>Remove</button></td>
                                                    </tr>
                                                )
                                            })
                                        }
                                
                                    
                                   
                                </tbody>
                            </Table>

Issue问题

The main issue in your code is that you've a bunch of buttons being rendered inside a form and nearly all of them don't specify a button type.您的代码中的主要问题是您在表单中呈现了一堆按钮,并且几乎所有按钮都没有指定按钮类型。 The default for buttons is type="submit" , so when any of them are clicked they are submitting the form and the form is taking the default submit action which also happens to reload the page.按钮的默认值为type="submit" ,因此当其中任何一个被单击时,它们正在提交表单并且表单正在执行默认提交操作,这也恰好重新加载页面。 When the page reloads your app reloads and loses the local component state.当页面重新加载您的应用程序重新加载并丢失本地组件 state。

Button type attribute按钮类型属性

The default behavior of the button.按钮的默认行为。 Possible values are:可能的值为:

  • submit : The button submits the form data to the server. submit :按钮将表单数据提交到服务器。 This is the default if the attribute is not specified for buttons associated with a <form> , or if the attribute is an empty or invalid value.如果没有为与<form>关联的按钮指定属性,或者该属性为空值或无效值,则这是默认值。
  • reset : The button resets all the controls to their initial values, like <input type="reset"> . reset :该按钮将所有控件重置为其初始值,例如<input type="reset"> (This behavior tends to annoy users.) (这种行为往往会惹恼用户。)
  • button : The button has no default behavior, and does nothing when pressed by default. button :按钮没有默认行为,默认按下时什么也不做。 It can have client-side scripts listen to the element's events, which are triggered when the events occur.它可以让客户端脚本监听元素的事件,这些事件在事件发生时触发。

Solution解决方案

Explicitly specify the button types.明确指定按钮类型。

  • The delete button删除按钮

     <button type="button" // <-- "button" type onClick={() => { removeItem(item); }} > Remove </button>
  • The form buttons to submit, reset, and open the modal提交、重置和打开模式的表单按钮

     <Button variant="primary" type="submit"> <-- "submit" type Submit </Button> <Button variant="primary" type="reset" // <-- "reset" type style={{ margin: '0 20px' }} > Reset Form </Button> <Button variant="primary" type="button" // <-- "button" type onClick={handleShow} style={{ margin: '0 15px' }} > Add Experience </Button>

Note: The submit button is still going to submit the form and since you've not any onSubmit callback on the Form component this button, as-is, will cause the page to reload.注意:提交按钮仍将提交表单,并且由于您在Form组件上没有任何onSubmit回调,因此该按钮将导致页面重新加载。 You will want to add a submit handler and call preventDefault on the onSubmit event object.您需要添加一个提交处理程序并在onSubmit事件 object 上调用preventDefault

const submitHandler = e => {
  e.preventDefault();
  // handle form data or whatever
};

...

<Form onSubmit={submitHandler}>
  ...

Generally we should not remove any item from array based on it's index.通常我们不应该根据它的索引从数组中删除任何项目。 So try to remove items based on unique values:-因此,请尝试根据唯一值删除项目:-

  const removeItem = item => {
    itemList(oldList => {
      return oldList.filter((arrEle, i) => arrEle.companyName !== item.companyName);
    });
  };

And pass item in removeItem function like below:-并在removeItem function 中传递item ,如下所示: -

onClick={() => removeItem(item)}

Add key to tr like below:-key添加到tr如下所示:-

<tr key={`${item.companyName}-${index}`}>

Working demo: https://stackblitz.com/edit/react-cxkbge工作演示: https://stackblitz.com/edit/react-cxkbge

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM