javascript 为什么不能删除数组中的任务?

monwx1rj  于 2023-05-05  发布在  Java
关注(0)|答案(4)|浏览(151)

我希望通过过滤删除App.js数组中的任务。但是在Task子组件中单击delete按钮后,数组保持不变。即使我传递的是id作为函数属性。

// App.js component

function App() {
  const [tasks, setTasks] = useState(Tasks);

  const deleteTask = (id) => {
    Tasks.filter((task) => task.id === id);
  };
  
  return (

<TaskComponent
  Tasks={tasks}
  changeTask={changeTask}
  deleteTask={deleteTask}
/>
)

// TaskComponent

type Tasks = {
  id: string;
  title: string;
  author_name: string;
  description: string;
  status: number | any;
  priority: number | any;
};

type Props = {
  Tasks: Tasks[];
  changeTask: (tasks: Tasks) => {};
  deleteTask: (tasks: Tasks) => {};
};

const TaskComponent: FC<Props> = ({ Tasks, changeTask, deleteTask }) => {
  const history = useHistory();

  const { id } = useParams<IdParams>();

  const task = Tasks.find((task) => String(task.id) === id);

  const [status, setStatus] = useState(task?.status);
  const [priority, setPriority] = useState(task?.priority);

  const handleDeleteTask = () => {
    deleteTask({
      ...task,
      id
    });

    history.push("/taskslist");
  };
  
  return (
  <form>
    <input type="button" value="delete" onClick={handleDeleteTask} />
  </form>
  )

CodeSandbox

93ze6v8z

93ze6v8z1#

  1. TaskComponent中的任务属性应为camelCase
  2. TaskComponent -无需在名称中包含Component
  3. handleDeleteTask正确命名,但它做什么?调用名为deleteTask的回调...然后...做一些与历史无关的事情。
    什么是deleteTask?是否需要使用TaskComponent的新Tasks值更新TaskComponent上方的状态,即不包括该任务的任务的选择。
    所以你的问题在于:
const deleteTask = (id) => {
  Tasks.filter((task) => task.id === id);
};

筛选器是否删除任务?否-好的,所以也许你需要map / reduce / filter来创建一个新的引用对象,而不需要删除和更新父对象中的状态的任务。使用setTasks

const deleteTask = (id) => {
   setTasks(tasks.filter((task) => task.id === id))
 };
kpbwa7wx

kpbwa7wx2#

看起来你需要使用setter方法setTasks来在你的应用上设置tasks prop,如下所示:

const deleteTask = (id) => {
   setTasks(tasks.filter((task) => task.id === id))
 };
luaexgnf

luaexgnf3#

问题:-直接过滤问题页面没有重新渲染的任务列表。

const deleteTask = (id) => {
    Tasks.filter((task) => task.id === id);
 };

解决方案:-

const deleteTask = (id) => {
    let newtask = task.filter((task) => task.id !== id);
     setTasks([...newtask]);
 };
jtoj6r0c

jtoj6r0c4#

1.您实际上应该只将一个任务的数据传递给Task组件。您可以通过使用map来迭代任务数组,并为每个任务返回一个Task组件,其中只包含所需的props。如果您使用history只显示一个任务,那么使用history的id获取任务的过程应该在App组件中使用filter完成,而不是在Task组件本身完成。
1.因为deleteTask只接受一个id,所以你只需要传递给它一个id。此时你正在传递一个对象。
1.在deleteTask中,你应该过滤掉所有id * 不 * 匹配作为参数传入的id的任务。
1.您需要使用filter返回的数组设置一个新的状态。
1.注意你的大写- JS是大小写敏感的。例如,在deleteTask中,您尝试在Tasks上过滤filter,而您应该在tasks上过滤。
1.如果你的任务数据集没有id,我建议你添加它们。这样,您既可以将它们用作迭代的Task组件上的键,也可以通过将该id分配给delete按钮来标识应该删除哪个任务。
我写了两个简短的例子来说明这些要点。第一个演示如何对数据执行map,以使用Task组件生成一系列任务,第二个演示如何使用history只显示一个任务。

示例一
const { useState } = React;

// For the sake of convenience I'm
// passing in an array of predefined tasks
function App({ data }) {
  
  // And I'm setting state with those tasks
  const [tasks, setTasks] = useState(data);

  // `filter` returns a new array - you want to filter
  // out (return) all those tasks that don't match the id
  // that you pass in as an argument. You then need to set
  // the state with that new filtered array
  function deleteTask(id) {
    const filtered = tasks.filter(task => {
      return task.id !== id;
    });
    setTasks(filtered);
  };
  
  // `map` over the tasks in state and for each
  // one pass down the relevant data to the
  // `Task` component
  return (
    <main>
      {tasks.map(task => {
        return (
          <Task
            key={task.id}
            data={task}
            deleteTask={deleteTask}
          />
        );
      })}
    </main>
  );

}

function Task({ data, deleteTask }) {

  // Call `delete` task with the id from
  // the button's dataset
  function handleDelete(e) {
    deleteTask(Number(e.target.dataset.id));
  }
  
  return (
    <section>
      {data.text}
      <button
        data-id={data.id}
        type="button"
        onClick={handleDelete}
      >Delete
      </button>
    </section>
  );

}

const tasks = [
  { id: 1, text: 'Task 1', status: 'incomplete', priority: 1},
  { id: 2, text: 'Task 2', status: 'incomplete', priority: 2},
  { id: 3, text: 'Task 3', status: 'complete', priority: 3}
];

const node = document.getElementById('root');
const root = ReactDOM.createRoot(node);
root.render(<App data={tasks} />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
<div id="root"></div>
示例二

这通过在App props中传递一个history对象来模拟useHistory,这样您就可以看到如何只获取通过id传递的任务。它使用额外的useEffect来显示删除任务后的任务状态。

const { useEffect, useState } = React;

// For the sake of convenience I'm
// passing in an array of predefined tasks,
// and a mock history object
function App({ data, history }) {
  
  const [tasks, setTasks] = useState(data);

  // Getting the id from history
  const { id } = history;

  function deleteTask(id) {
    const filtered = tasks.filter(task => {
      return task.id !== id;
    });
    setTasks(filtered);
  };
  
  // Get only the task that has an id that
  // matches the id from history
  function getTask(id) {
    return tasks.filter(task => task.id === id);
  }

  // An effect to show how the state changes
  useEffect(() => {
    console.log(JSON.stringify(tasks));
  }, [tasks]);

  // Get the task corresponding to the id from
  // history - `getTask` uses `filter` which returns
  // an array so we can still `map` over the result
  return (
    <main>
      {getTask(id).map(task => {
        return (
          <Task
            key={task.id}
            data={task}
            deleteTask={deleteTask}
          />
        );
      })}
    </main>
  );

}

function Task({ data, deleteTask }) {

  // Call `delete` task with the id from
  // the button's dataset
  function handleDelete(e) {
    deleteTask(Number(e.target.dataset.id));
  }
  
  return (
    <section>
      {data.text}
      <button
        data-id={data.id}
        type="button"
        onClick={handleDelete}
      >Delete
      </button>
    </section>
  );

}

const tasks = [
  { id: 1, text: 'Task 1', status: 'incomplete', priority: 1},
  { id: 2, text: 'Task 2', status: 'incomplete', priority: 2},
  { id: 3, text: 'Task 3', status: 'complete', priority: 3}
];

const myHistory = {
  id: 2
};

const node = document.getElementById('root');
const root = ReactDOM.createRoot(node);
root.render(<App data={tasks} history={myHistory} />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
<div id="root"></div>

相关问题