You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS批量删除选中商品问题求助:移除勾选的商品卡片

问题修复:批量删除勾选的商品卡片

核心问题分析

  • 复选框的value是字符串类型的索引,但删除逻辑中用数字索引匹配isChecked数组,类型不匹配导致过滤失效。
  • 复选框选中状态未与isChecked数组绑定,导致状态混乱。
  • 删除操作后未清空isChecked数组,影响后续删除逻辑。

修复步骤

1. 统一索引类型

将复选框的value转为数字,确保isChecked数组存储数字索引:

const handlecheckbox = (e)=>{
  const value = Number(e.target.value);
  const { checked } = e.target;
  if(checked){
    setIsChecked(prev => [...prev, value]);
  } else {
    setIsChecked(prev => prev.filter(item => item !== value));
  }
}

2. 删除后清空勾选状态

删除完成后重置isChecked数组,避免残留状态影响后续操作:

const deleteItem = () => {
  const newProductsArr = productsArr.filter((_, index) => !isChecked.includes(index));  
  setProductsArr(newProductsArr);
  setIsChecked([]);
}

3. 修复复选框选中状态绑定

将复选框的checked属性改为判断当前索引是否在isChecked数组中,同时把isChecked传递给ProductList组件:

// App.js中传递isChecked
<Route exact path="/" element={<ProductList deleteItem={deleteItem} handlecheckbox={handlecheckbox} products={productsArr} isChecked={isChecked} />} />

// ProductList中修改复选框
<input 
  className='delete-checkbox' 
  type="checkbox" 
  value={index} 
  checked={props.isChecked.includes(index)}
  onChange={(e)=>props.handlecheckbox(e)}
/>

4. 优化表单提交逻辑

将AddProduct中的Link改为button,使用form的submit事件触发添加,避免表单未验证就跳转:

// AddProduct组件中修改表单
<form id='product_form' onSubmit={props.addProduct}>
  {/* ... 其他表单元素 ... */}
  <button type="submit" id='save-btn'>SAVE</button>
</form>

修改后的完整代码

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(prev => ({
      ...prev,  
      [e.target.name]: e.target.value
    }));
  };  

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

  const handlecheckbox = (e)=>{
    const value = Number(e.target.value);
    const { checked } = e.target;
    if(checked){
      setIsChecked(prev => [...prev, value]);
    } else {
      setIsChecked(prev => prev.filter(item => item !== value));
    }
  }

  const deleteItem = () => {
    const newProductsArr = productsArr.filter((_, index) => !isChecked.includes(index));  
    setProductsArr(newProductsArr);
    setIsChecked([]);
  }

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

export default App;

ProductList组件

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>{''}
            <button onClick={props.deleteItem} id='delete-btn'>MASS DELETE</button>{''}
          </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={props.isChecked.includes(index)}
                  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}</p>
                </div>
              </div>
            </div>
          )
        })}
    </div>
  )
} 

export default ProductList;

AddProduct组件

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);
  }  
  
  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' onSubmit={props.addProduct}>
                <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="number" name="Price" id="price" required/>
                </div>
                <label htmlFor="type">Type Switcher: </label>
                <select onChange={formTypeChange} value={type} name="type" id="productType" required>
                    <option 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 Length (CM): </label>
                    <input onChange={props.handlerChange} value={props.products.Size} type="text" name="Size" id="HxWxL" required/>
                    <p>* Please provide dimensions of furniture in H x W x L.</p>
                  </div>
                ) : null}
            </div>
            <button type="submit" id='save-btn'>SAVE</button>
            </form>
        </div>
    </div>
  )
}

export default AddProduct;

内容的提问来源于stack exchange,提问作者Altug Okumus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 13:33:10