0

inputValue is an array of objects that I want to remove from the element that I click its deleting button. element declared with useState, and passed as a prop after. I used indexOf to navigate its place and remove it with splice, but instead it removing all of the elements except the first one, it ... ?

import React from "react";

function Todo({ element, inputValue, setInputValue }) {
  const deleteHandler = () => {
    setInputValue(inputValue.splice(inputValue.indexOf(element), 1));
    console.log(inputValue.indexOf(element));
    console.log(element.id);
  };

  const completeHandler = () => {
    console.log(element.id);
    console.log(inputValue.indexOf(element));
  };

  return (
    <div className="todo">
      {element.text}{" "}
      <div>
        <button onClick={deleteHandler}>delete</button>{" "}
        <button onClick={completeHandler}>complete?</button>
      </div>
    </div>
  );
}

export default Todo;
machineghost
  • 33,529
  • 30
  • 159
  • 234

3 Answers3

2

.splice() returns an array containing the deleted elements. Your deletion is working well.

On a side note, you should not be mutating the props like that. .splice() modifies in place.(This is for the sake of pure functions, react likes it that way.) Make a copy.

let newInputValueArr = [...inputValue];
newInputValueArr.splice(newInputValueArr .indexOf(element), 1)
setInputValue(newInputValueArr, 1));

Note: this assumes your array has only simple items. Also, .indexOf() will only work for those, and not objects.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

Return value

An array containing the deleted elements.

It modifies the array in place. I would just use filter which returns a copy of the array as this is a state variable.

ex.

setInputValue(inputValue.filter(value => value != element));

ᴓᴓᴓ
  • 1,178
  • 1
  • 7
  • 18
1

You are using splice incorrectly on this line:

setInputValue(inputValue.splice(inputValue.indexOf(element), 1));

Specifically, you are setting the return value of your splice ... but splice returns the values you removed, NOT the new array with the removed values.

What you need to do instead is splice the array, and then set it separately, after the splice has completed:

inputValue.splice(inputValue.indexOf(element), 1);
setInputValue(inputValue);

This way the splice line will modify your input value, as desired, and its return value (of the removed elements) simply won't be used (as you no longer pass that returned value to any function). Then, on the next line, you'll set the new, post-splice version of inputValue in your state.

For further information on how splice works see its page on the MDN.

P.S. You could also solve this problem without using splice at all. For instance, you could use the Array prototype filter method to filter the records you want out, or you could use Lodash's without function, which returns a version of an array with certain elements removed. With either of those approaches you could set their returned value directly, as your original code did.

machineghost
  • 33,529
  • 30
  • 159
  • 234