使用功能组件/挂钩从 React 中的数组中删除特定项目

Posted

技术标签:

【中文标题】使用功能组件/挂钩从 React 中的数组中删除特定项目【英文标题】:Deleting Specific Item From Array in React using Functional Components/Hooks 【发布时间】:2021-03-13 02:42:24 【问题描述】:

我正在尝试删除数组中的一项。但是,我的删除按钮没有执行我的代码,并且数组保持不变。我不知道该怎么办。

我的代码如下:

//App.js

import React,  useState  from "react";
import Overview from "./components/Overview";

function App() 
  const [task, setTask] = useState("");
  const [tasks, setTasks] = useState([]);

  function handleChange(e) 
    setTask(e.target.value);
  

  function onSubmitTask(e) 
    e.preventDefault();
    setTasks(tasks.concat(task));
    setTask("");
  

  //error happening here????---------------------------------------------------
  function removeTask(itemId) 
      setTasks(prevState => prevState.filter(( id ) => id !== itemId));
  


  return (
    <div className="col-6 mx-auto mt-5">
      <form onSubmit=onSubmitTask>
        <div className="form-group">
          <label htmlFor="taskInput">Enter task</label>
          <input
            onChange=handleChange
            value=task
            type="text"
            id="taskInput"
            className="form-control"
          />
        </div>
        <div className="form-group">
          <button type="submit" className="btn btn-primary">
            Add Task
          </button>
        </div>
      </form>
      <Overview tasks=tasks removeTask=removeTask />
    </div>
  );


export default App;

子组件:

import React from "react";

function Overview(props) 
  const  tasks, removeTask  = props;
  console.log(tasks)
  return (
    <>
      tasks.map((task, index) => 
        return (
          <>
            <p key=index>
              #index + 1 task
            </p>
            //this onClick isn't doing anything-------------------------------------
            <button onClick=() => removeTask(index)>Delete Task</button>
          </>
        );
      )
    </>
  );

export default Overview;

我的“任务”状态给了我一个数组,里面的项目是字符串。但是,当我尝试过滤数组时,它不起作用。因此,我没有按值过滤,而是尝试按 id/index 过滤。由于索引会匹配它,我认为这会从数组中删除该项目,即使只有一个项目,它也不会删除任何内容,并且删除按钮只是控制台记录给定的数组。

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

问题

您的 delete 方法使用了一个项目 id,但您在按钮的 onClick 处理程序中向它传递了一个索引。

解决方案

id 或索引中选择一个或另一个,并保持一致。

使用id

function removeTask(itemId) 
  setTasks(prevState => prevState.filter(( id ) => id !== itemId));


...

<button onClick=() => removeTask(task.id)>Delete Task</button>

使用索引

function removeTask(itemIndex) 
  setTasks(prevState => prevState.filter((_, index) => index !== itemIndex));


...

<button onClick=() => removeTask(index)>Delete Task</button>

由于您的任务看起来不是具有id 属性的对象,因此我建议在您的任务中添加id。这将在您以后从列表中成功删除任务时为您提供帮助,因为您还希望使用数组索引作为反应键,因为您希望改变您的任务数组。

App.js

import  v4 as uuidV4  from 'uuid';

...

function onSubmitTask(e) 
  e.preventDefault();
  setTasks(prevTasks => prevTasks.concat(
    id: uuidV4(), // <-- generate new id
    task
  ));
  setTask("");


function removeTask(itemId) 
  setTasks(prevState => prevState.filter(( id ) => id !== itemId));

孩子

function Overview( tasks, removeTask ) 
  return (
    tasks.map(( id, task , index) =>  // <-- destructure id & task
      return (
        <Fragment key=id> // <-- react key on outer-most element
          <p>
            #index + 1 task
          </p>
          <button onClick=() => removeTask(id)>Delete Task</button>
        </>
      );
    )
  );

【讨论】:

【参考方案2】:

我认为你需要在这里传递taskId 而不是index

<button onClick=() => removeTask(task.id /*index*/)>Delete Task</button>

因为removeTask 函数处理的是taskId 而不是index


但是看起来你在tasks 上没有id 字段,即使你假设它在setTasks(prevState =&gt; prevState.filter(( id ) =&gt; id !== itemId)); 中,所以如果你想继续按索引删除任务,请更改removeTask 如下。

function removeTask(index)  // remove by index
    setTasks(prevState => 
        const tasks = [...prevState]; // create new array based on current tasks
        tasks.splice(index, 1); // remove task by index
        return tasks; // return altered array
    );

demo

【讨论】:

以上是关于使用功能组件/挂钩从 React 中的数组中删除特定项目的主要内容,如果未能解决你的问题,请参考以下文章

试图从 React 中的对象数组中删除一个项目

在 React Native 中的类中挂钩

如何从使用状态挂钩的功能性父组件传递道具?

如何使用 React useRef 挂钩删除地图中的类

如何使用 React 删除列表项(功能组件)

react中从类重构为功能钩子组件