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

React中如何正确删除数组内动态添加的div面板

解决ConnectedProducts.js中删除面板时动态传递索引的问题

核心问题是你没有在点击删除按钮时把当前面板的动态索引/唯一标识存储下来,导致Modal始终拿到固定值。以下是具体的解决步骤和代码示例:

方案一:使用索引(适合无唯一ID的场景)

  1. 在组件中添加状态,存储当前要删除的面板索引和Modal的显示状态
  2. 点击删除按钮时,将当前面板的索引存入状态并打开Modal
  3. 确认删除时,利用存储的索引过滤数组
import { useState } from 'react';

const ConnectedProducts = () => {
  const [products, setProducts] = useState([/* 你的产品数据数组 */]);
  const [deleteTargetIndex, setDeleteTargetIndex] = useState(null);
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);

  // 打开删除确认框并记录当前面板索引
  const triggerDeleteModal = (index) => {
    setDeleteTargetIndex(index);
    setIsDeleteModalOpen(true);
  };

  // 执行删除操作
  const confirmDelete = () => {
    if (deleteTargetIndex === null) return;
    // 过滤掉目标索引的面板数据
    const updatedProducts = products.filter((_, idx) => idx !== deleteTargetIndex);
    setProducts(updatedProducts);
    // 关闭模态框并清空索引
    setIsDeleteModalOpen(false);
    setDeleteTargetIndex(null);
  };

  // 取消删除
  const cancelDelete = () => {
    setIsDeleteModalOpen(false);
    setDeleteTargetIndex(null);
  };

  return (
    <div>
      {/* 生成产品面板 */}
      {products.map((product, index) => (
        <div key={index} className="product-panel">
          {/* 面板内容 */}
          <h4>{product.name}</h4>
          {/* 绑定动态索引到删除按钮 */}
          <button onClick={() => triggerDeleteModal(index)}>删除</button>
        </div>
      ))}

      {/* 删除确认模态框 */}
      {isDeleteModalOpen && (
        <div className="delete-modal">
          <div className="modal-body">
            <p>确定要删除该产品吗?</p>
            <button onClick={confirmDelete}>确认删除</button>
            <button onClick={cancelDelete}>取消</button>
          </div>
        </div>
      )}
    </div>
  );
};

export default ConnectedProducts;

方案二:使用唯一ID(推荐,避免索引变化导致的错误)

如果你的产品数据中有唯一标识(如product.id),更推荐用ID来定位要删除的项——因为数组索引会随着元素增删、排序发生变化,可能导致删除错误。

import { useState } from 'react';

const ConnectedProducts = () => {
  const [products, setProducts] = useState([/* 你的产品数据数组,每个item含id字段 */]);
  const [deleteTargetId, setDeleteTargetId] = useState(null);
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);

  const triggerDeleteModal = (productId) => {
    setDeleteTargetId(productId);
    setIsDeleteModalOpen(true);
  };

  const confirmDelete = () => {
    if (!deleteTargetId) return;
    const updatedProducts = products.filter(product => product.id !== deleteTargetId);
    setProducts(updatedProducts);
    setIsDeleteModalOpen(false);
    setDeleteTargetId(null);
  };

  const cancelDelete = () => {
    setIsDeleteModalOpen(false);
    setDeleteTargetId(null);
  };

  return (
    <div>
      {products.map((product) => (
        {/* 用唯一ID作为key,避免渲染问题 */}
        <div key={product.id} className="product-panel">
          <h4>{product.name}</h4>
          <button onClick={() => triggerDeleteModal(product.id)}>删除</button>
        </div>
      ))}

      {isDeleteModalOpen && (
        <div className="delete-modal">
          <div className="modal-body">
            <p>确定要删除该产品吗?</p>
            <button onClick={confirmDelete}>确认删除</button>
            <button onClick={cancelDelete}>取消</button>
          </div>
        </div>
      )}
    </div>
  );
};

export default ConnectedProducts;

关键说明

  • 不要用固定的getIndex返回值,而是在点击按钮时直接传递当前项的索引/ID到状态中
  • 始终用状态来维护Modal的显示状态和目标删除项,确保Modal能拿到最新的目标信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:10:24