首页 > 解决方案 > React:如何在单击其关联按钮后删除特定的 div 元素?

问题描述

我有这个组件,它在按钮单击时将 div 及其元素添加到 dom。添加部分按预期工作正常,但是当我想删除时出现问题。

现在,当我单击删除按钮时,它会删除该项目,但不会删除与该按钮关联的特定项目。它只是从顶部或底部删除 div。

我一直在尝试删除其按钮已被单击删除的特定 div。我怎样才能做到这一点?

这是CodeSandbox

这是代码:

import { useState } from "react";

const App = () => {

  const [ counter, setCounter ] = useState( 1 );

  const handleAddDiv = () => {
    setCounter( counter + 1 );
  };

  const handleRemoveDiv = () => {
    setCounter( counter - 1 );
  };

  return (
    <div className="App">

      {
        Array.from(Array( counter )).map(( item, idx ) => (
           <div>
             <div>
               <input type="text" />
               <button onClick={handleRemoveDiv}>Remove</button>
             </div>
           </div>
        ))
      }

      <button onClick={handleAddDiv}>Add</button>

    </div>
  );
}
export default App;

标签: javascriptreactjsreact-hooks

解决方案


映射一组唯一 ID

首先,您应该映射项目数组而不是整数值。

因此,在单击添加按钮时,您应该将唯一的 ID推送到项目数组,其中每个 ID 表示您的应用程序中正在呈现的项目。

现在,当您单击删除按钮时,您需要从项目数组中删除该 ID,这将导致该 div 从应用程序中“删除”

在我的情况下,我考虑timestamp过作为唯一 ID,但应该探索其他选项来生成唯一 ID。在 React 中使用索引是一种反模式,尤其是当您在 JSX 中映射数组时,因为您会在某个时间点遇到问题。因此,保持唯一 ID 是一个好主意。

注意: Damian 的解决方案并不理想,因为在 React中避免了 DOM 操作。

const { useState, useCallback } = React;

const Item = ({ id, removeDiv }) => {
  const clickHandler = useCallback(() => {
    removeDiv(id);
  }, [id, removeDiv]);

  return (
    <div>
      <input type="text" />
      <button onClick={clickHandler}>Remove</button>
    </div>
  );
};

const App = () => {
  const [items, setItems] = useState([]);

  const addDiv = useCallback(() => {
    // using timestamp as a unique ID
    setItems([...items, new Date().getTime()]);
  }, [items]);

  const removeDiv = useCallback((itemId) => {
    // filter out the div which matches the ID
    setItems(items.filter((id) => id !== itemId));
  }, [items]);

  return (
    <div className="app">
      {items.map((id) => (
        <Item key={id} id={id} removeDiv={removeDiv} />
      ))}

      <button onClick={addDiv}>Add</button>
    </div>
  );
};

ReactDOM.render(<App />,document.getElementById("react"));
.app {
  text-align: center;
  font-family: sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>


推荐阅读