reactjsreact-hooksremovechild

click the button and if the items' checkbox checked delete the items ReactJS


I have two components. One is ProductList and the other one is AddProduct. PAddProduct has a form for the details for the product. After filling the form and click the button "Save" the pruduct details appears like a card on the ProductList component. All product details card have a checkbox. I want to delete one or more product details card when I click to delete button if checkbox is checked.

I try to use State to create an array of index numbers of the items when I check the checkbox. Then filter that index number from the products array and list the rest. But it did not work. Can you help me to fix this?

Here is my App.js :

import './App.css';
import ProductList from './Components/ProductList';
import {Routes, Route} from 'react-router-dom';
import AddProduct from './Components/AddProduct';
import { useState } from 'react';

function App() {

  const [productsArr, setProductsArr] = useState([]);
  const [isChecked, setIsChecked] = useState([]);

  const [products, setProducts] = useState({
    SKU: "",
    Name: "",
    Price: "",
    Size: ""
  })

  
  const handlerChange = (e) => {
    setProducts({
      ...products,  
      [e.target.name]: e.target.value
    });
     
  };  

  let {SKU, Name, Price, Size} = products;
  const addProduct = (e)=> {
    setProductsArr([...productsArr, {SKU, Name, Price, Size}])
    setProducts({
      SKU: "",
      Name: "",
      Price: "",
      Size: ""
    })
    e.preventDefault()
  }

  const handlecheckbox = (e)=>{
    const {value, checked} = e.target;
    if(e.target.checked){
      setIsChecked([...isChecked, value]);
      console.log(isChecked)
    } else {
      setIsChecked(isChecked.filter((e)=> e !== value));
      console.log(isChecked)
    }
  }

  const deleteItem = () => {
    const newProductsArr = productsArr.filter((obj, index) => !isChecked.includes(index));  
    setProductsArr(newProductsArr);
    console.log(newProductsArr);
    console.log(isChecked);
    console.log(productsArr);
  }

  return (
    <>
      <Routes>
        <Route exact path="/" element={<ProductList deleteItem={deleteItem} handlecheckbox={handlecheckbox} products={productsArr} />} />
        <Route path="/addproduct" element={<AddProduct products={products} addProduct={addProduct} handlerChange={handlerChange} />} />
      </Routes>
    </>
  );
}

export default App;

Here ProductList component:

import React from 'react'
import { Link } from 'react-router-dom';


function ProductList(props) {

  
  

  return (
    <div className='main'>
        <div className='navbar'>
          <div className='header'>
            <h3>Product List</h3>
          </div>
          <div className='btn'>
            <Link to={"/addproduct"} id='add-btn'>ADD</Link>{''}
            <Link onClick={props.deleteItem} to={"/"} id='delete-btn'>MASS DELETE</Link>{''}
          </div>
        </div>
        {props.products.map((product, index) => {
          return <div key={index} id={index}  className="card-container">
         
          <div className='product-card'>
          <input className='delete-checkbox' type="checkbox" value={index} checked={product.isChecked} onChange={(e)=>props.handlecheckbox(e)}/>
             <div className='item-info'>  
                <h5>{product.SKU}</h5>
                <p>{product.Name}</p>
                <p>{product.Price}</p>
                <p>Size: {product.Size} {product.SizeH} {product.SizeW} {product.SizeL} </p>
              </div>
            </div>
          
          </div>
        })}
    </div>
  )
} 

export default ProductList;

Here AddProduct component:

import React, { useState } from 'react'
import { Link } from 'react-router-dom';

function AddProduct(props) {

  const [type, setType] = useState("");  

  const formTypeChange = (e) => {
    setType(e.target.value);
    e.preventDefault();
  }  
  
  return (

    <div className='main'>
      <div className='navbar'>
          <div className='header'>
            <h3>Product Add</h3>
          </div>
          <div className='btn'>
            <Link to={"/"} id='cancel-btn'>CANCEL</Link>{''}
          </div>
        </div>
        <div>
            <form id='product_form'>
                <div>
                  <label htmlFor="sku">SKU:</label>
                  <input onChange={props.handlerChange} value={props.products.SKU} type="text" name="SKU" id="sku" required/> 
                </div>
                <div>
                  <label htmlFor="name">Name:</label>
                  <input onChange={props.handlerChange} value={props.products.Name} type="text" name="Name" id="name" required/>
                </div>
                <div>
                  <label htmlFor="price">Price ($):</label>
                  <input onChange={props.handlerChange} value={props.products.Price} type="price" name="Price" id="price" required/>
                </div>
                <label htmlFor="type">Type Switcher: </label>
                <select onChange={formTypeChange} value="" name="type" id="productType" required>
                    <option disabled="disabled" value="" >--Please choose product type--</option>
                    <option value="dvd">DVD</option>
                    <option value="book">Book</option>
                    <option value="furniture">Furniture</option>
                 </select>
            
            <div id='size-section'>
                { type === "dvd" ? (
                  <div id='DVD'>
                    <label htmlFor="Size">Size (MB): </label>
                    <input onChange={props.handlerChange} value={props.products.Size} type="number" name="Size" id="size" required/>
                    <p>* Please provide size of DVD in MB.</p>
                  </div>
                ) : type === "book" ? (
                  <div id='Book'>
                    <label htmlFor="Size">Size (Kg): </label>
                    <input onChange={props.handlerChange} value={props.products.Size} type="number" name="Size" id="weight" required/>
                    <p>* Please provide size of book in Kg.</p>
                  </div>
                ) : type === "furniture" ? (
                  <div id='Furniture'>
                    <label htmlFor="size-h">Height x Width x Lenght (CM): </label>
                    <input onChange={props.handlerChange} value={props.products.Size} type="text" name="Size" id="HxWxL" required/>
                    <p>* Please provide dimentions of furniture in H x W x L.</p>
                  </div>
                ) : (
                  <h1></h1>
                )}
            </div>
            <Link to={"/"} onClick={props.addProduct} id='save-btn'>SAVE</Link>{''}
            </form>
        </div>
    </div>
  )
}

export default AddProduct;

Solution

  • There's a slight problem with the check inside the filter() in deleteItem() function:

    const newProductsArr = productsArr.filter((obj, index) => {
       // isChecked contains strings: "0", "1"
       // index is a number: 0, 1
       return !isChecked.includes(index);
    });
    

    Fix:

    const newProductsArr = productsArr.filter((obj, index) => {
       return !isChecked.includes(String(index));
    });