#reactjs #react-hooks #react-functional-component
#reactjs #реагирующие перехваты #react-functional-component
Вопрос:
Я пытаюсь удалить элемент в массиве. Однако моя кнопка удаления не выполняет мой код, и массив остается неизменным. Я не уверен, что делать.
Мой код приведен ниже:
//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;
Мое состояние «задачи» дает мне массив с элементами внутри в виде строк. Однако, когда я попытался отфильтровать массив, это не сработало. Поэтому вместо фильтрации по значению я попытался фильтровать по идентификатору / индексу. Поскольку индекс будет соответствовать ему, я подумал, что это удалит элемент из массива, даже если есть только один элемент, он ничего не удаляет, а кнопка удаления просто регистрирует в консоли данный массив.
Любая помощь будет принята с благодарностью.
Ответ №1:
Я думаю, вам нужно передать taskId
вместо index
здесь
<button onClick={() => removeTask(task.id /*index*/)}>Delete Task</button>
поскольку removeTask
функция имеет дело taskId
не с index
Однако похоже, что у вас нет id
поля tasks
, даже если вы предполагаете, что оно есть setTasks(prevState => prevState.filter(({ id }) => 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
});
}
Ответ №2:
Проблема
Ваш метод удаления использует идентификатор элемента, но вы передаете ему индекс в обработчике кнопки onClick
.
Решение
Выберите один или другой из id
or index и оставайтесь последовательными.
Использование 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
свойством, я предлагаю добавить an 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 amp; task
return (
<Fragment key={id}> // <-- react key on outer-most element
<p>
#{index 1} {task}
</p>
<button onClick={() => removeTask(id)}>Delete Task</button>
</>
);
})}
);
}