I have an array off which I would like to delete elements upon clicking the delete button. However, the problem with this is that only the data at the gets deleted no matter where I click leaving the data at that index intact. I would like to know what I can do to ensure this works normally. Below is my code:
import { useEffect, useState } from "react";
const Task = () => {
const [todos, setTodos] = useState([]);
useEffect(() => {
fetch('http://jsonplaceholder.typicode.com/todos')
.then(res => res.json())
.then(data => {
setTodos(data)
})
}, []);
//Using splice
// const deleteTodo = (index) => {
// const temp = [...todos];
// temp.splice(index, 1);
// setTodos(temp);
// console.log(index);
// // console.log(`newData : ${arr} || newLength : ${arr.length}`);
// console.log(`newLength : ${todos.length}`);
// }
//Using Filter
const deleteTodo = (index) => {
const newTodo = todos.filter(todo => todo.id !== index);
setTodos(newTodo);
console.log(`newLength : ${todos.length}`);
}
return (
<div className='container'>
<table className='table'>
<tbody>
{todos.map((key, value) => (
<tr key={key.id}>
<td>{todos[value].id}</td>
<td>{todos[value].title}</td>
<td>{`${todos[value].completed}`}</td>
<td>
<button className='btn btn-danger ' onClick={() => deleteTodo(key)}> Delete </button>
</td>
</tr>
))}
</tbody>
</table>
<button className='btn btn-primary'>Add Task</button>
</div>
);
}
export default Task;
I have tried both the splice and the filter methods.
The splice method deletes data only off the top irrespective of the data I delete whereas the filter method doesn’t do anything at all as shown on the snippet below. The length remains the same even after clicking the delete button.
>Solution :
In .map()
method the first argument – current array item, the second – index. You pass the current array item to your deleteTodo
func, instead of passing id
(deleteTodo(key.id)
).
It should be like this:
const deleteTodo = (index) => {
const newTodo = todos.filter(todo => todo.id !== index);
setTodos(newTodo);
console.log(`newLength : ${todos.length}`);
}
return (
<div className='container'>
<table className='table'>
<tbody>
{todos.map((key, value) => (
<tr key={key.id}>
<td>{todos[value].id}</td>
<td>{todos[value].title}</td>
<td>{`${todos[value].completed}`}</td>
<td>
<button className='btn btn-danger ' onClick={() => deleteTodo(key.id)}> Delete </button>
</td>
</tr>
))}
</tbody>
</table>
<button className='btn btn-primary'>Add Task</button>
</div>
);
Also you don’t need to do todos[value]
as you already have a current item.
You could use this:
todos.map((item, index) => (<>
<td>{item.id}</td>
<td>{item.title}</td>
</>)