0

So I'm doing the splice method usually when I use it but it's not working in this situation... I have no idea why. When I pass the deleteToDo function it deletes everything. Like 4 items... I was trying to explain the concept to someone but I guess I don't understand because I wrote this to explain it and it didn't work lol. Oops!

I thought this would remove the specific item by index, but it doesn't work. Can anyone explain what I'm doing wrong? It looks similar to other solutions I've seen here but idk. Thanks in advance!

Specifically these lines:

 // Deletes item from todos
  const deleteToDo = (toDo) => {
    let results = todos.splice(toDo, 1);
    setTodos(results);
  };

Here's the simple code in it's entirety.

import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";

const App = () => {
  // State Managment
  const [todos, setTodos] = useState([]);
  const [name, setName] = useState("Logan");
  const [todo, setTodo] = useState("");

  // set's todo as input box
  const updateToDO = (e) => {
    setTodo(e.target.value);
  };

  // Updates todos state
  const updateList = (e) => {
    const results = todos.concat(todo);
    setTodos(results);
    setTodo("");
  };

  // Deletes item from todos
  const deleteToDo = (toDo) => {
    let results = todos.splice(toDo, 1);
    setTodos(results);
  };

  return (
    <div className="container">
      <h1>Todo's for {name} </h1>

      <input value={todo} onChange={updateToDO} type="text" />

      <button onClick={updateList}>Add To Do</button>

      <AnimatePresence>
        {/* loops through todos */}
        {todos.map((todo, id) => (
          <motion.div
            key={id}
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="card"
          >
            <div className="card-body">
              <h3>{todo}</h3>
              <button
                onClick={() => {
                  deleteToDo(id);
                }}
              >
                Delete
              </button>
            </div>
          </motion.div>
        ))}
      </AnimatePresence>
    </div>
  );
};

export default App;


Ivcota
  • 29
  • 3

1 Answers1

3

The return value of the splice method are the elements REMOVED from the original array, not the array without the removed elements. I think the splice method is working just fine, you are using it wrong.

You shouldn't use splice in a variable handled by useState cause splice changes the original array. You should copy it and then set it:

const deleteToDo = (toDo) => {
  const aux = [...todos];
  aux.splice(toDo, 1);
  setTodos(aux);
};
arieljuod
  • 13,456
  • 2
  • 19
  • 31
  • Oh I wasn't saying the the method isn't working... I meant the way I was using it wasn't working. I totally understand now, and this is all because of React's immutability, and the same way you can't push to an array you can't just splice!! – Ivcota Oct 04 '20 at 03:38