Item in array getting deleted from top only

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.

enter image description here

>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>
</>)

Leave a Reply