简体   繁体   中英

array.splice(index, 1) returns array with removed item

I am learning react hooks and I am just trying to do a simple function to remove the item from the list. To do this I am using find, indexOf, and splice.

In the onClick function, I am using the indexOf in the array.splice(indexOf, 1), BUT it returns just the item from the list. Everything rerenders and does what it is supposed to do, but the only itme that renders is the item that I just tried to delete. What am I missing?

const [todos, setToDo] = useState(initialToDo);
const [input, setInput] = useState('');

const todoList = (todos) => {
    return (
        todos.map((todo) => {
        return (
            <div className='todo-list flex p-2 w-1/2 justify-between'>
                <p className="px-3">{todo.name}</p>
                <button 
                    className='rounded-sm border-2 px-2'
                    onClick={(e)=>{
                        let item = todos.find(el=>el.id == todo.id);
                        console.log(item)
                        let index = todos.indexOf(item);
                        console.log(index)
                        todos = todos.splice(index, 1)
                        // todos == item
                        setToDo(todos)
                    }}    
                >-</button>
            </div>
    )}))
}

Yes, Array.splice returns the removed element and mutates the original array, which mean you can use index to delete/update the todo from todos list.

Simplest way of doing this, is the following way. Here's the working example

const todoList = () => {
  const [todos, setToDo] = useState(initialToDo);
  const [input, setInput] = useState('');

  const handleDelete = index => {
    todos.splice(index, 1)
    setToDo([...todos])
  }

  return (
    todos.map((todo, index) => {
    return (
      <div className='todo-list flex p-2 w-1/2 justify-between'>
        <p className="px-3">{todo.name}</p>
        <button 
          className='rounded-sm border-2 px-2'
          onClick={() => handleDelete(index)}    
        >
        -
       </button>
      </div>
  )}))
}

splice returns the deleted items. I recommend using filter instead, something like:

setToDo(todos.filter(({ id }) => id != todo.id));

Use filter instead of mutating with splice . Try this snippet.

 const TodoList = () => { const [todos, setTodos] = React.useState([ { name: 'a', id: 1 }, { name: 'b', id: 2 }, ]); return todos.map((todo) => { return ( <div> <p>{todo.name}</p> <button onClick={() => setTodos(todos.filter(item => item.id.== todo;id))} > - </button> </div> ); }); }. const domContainer = document;querySelector('#app'). ReactDOM,render(<TodoList />; domContainer);
 <script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script> <div id="app"> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM