lyes makhloufi
lyes makhloufi

Reputation: 59

Delete from state in react

I'm facing a problem when I try to delete an item from an array in react state, only one element remains in the array containing all the other item's contents.

Here is a sandbox describing the problem.

Has anyone an idea for that behaviour ?

App.js

import React, { useEffect, useState } from "react";
import { Button, Input } from "semantic-ui-react";
import "./App.css";
import Item from "./components/Item";

function App() {
  const [todos, setTodos] = useState([]);
  const [todo, setTodo] = useState("");
  const [emptyError, setEmptyError] = useState(false);

  const handleClick = () => {
    if (todo.length === 0) {
      setEmptyError(true);
    } else {
      todos.push(todo);
      setTodos(todos);
      setTodo("");
    }
  };

  const handleChange = (e) => {
    setTodo(e.target.value);
    if (e.target.value.length > 0) {
      setEmptyError(false);
    }
  };

  const handleDelete = (e) => {
    e.stopPropagation();
    console.log(e.target.parentNode.id)
    setTodos(todos.filter((item, index) => index !== +e.target.parentNode.id));
  };

  return (
    <div className="App">
      <div className="inputArea">
        {" "}
        <input
          class="form-control"
          onChange={handleChange}
          value={todo}
          type="text"
          placeholder="Enter todo"
        ></input>{" "}
        <button onClick={handleClick} type="button" class="btn btn-dark">
          Add todo
        </button>
      </div>
      {!emptyError ? (
        ""
      ) : (
        <div className="error"> Todo can't be empty, please add a todo </div>
      )}
      <div className="todoList">
        {todos.map((item, index) => {
          return <Item text={item} delete={handleDelete} id={index} />;
        })}
      </div>
    </div>
  );
}

export default App;

Upvotes: 1

Views: 50

Answers (2)

Yoel
Yoel

Reputation: 7965

you need convert string to number

you can do it with the help of the Number constructor

setTodos( todos.filter((item, index) => index!==Number(e.target.parentNode.id))

Upvotes: 0

zmag
zmag

Reputation: 8241

  1. You need to remove bracket in setTodos.
  2. id of the element is a string. It has to be converted to number if you compare them with ===.
setTodos([todos.filter((item, index) => index !== e.target.parentNode.id)]);

to be:

setTodos(todos.filter((item, index) => index !== +e.target.parentNode.id));

Upvotes: 1

Related Questions