Tengo una variedad de objetos. Necesito agregar una función para eliminar un objeto de mi matriz sin usar la palabra clave "esto".
Intenté usar updateList(list.slice(list.indexOf(e.target.name, 1))) . Esto elimina todo menos el último elemento de la matriz y no estoy seguro de por qué.
const defaultList = [ { name: "ItemOne" }, { name: "ItemTwo" }, { name: "ItemThree" }] const [list, updateList] = useState(defaultList); const handleRemoveItem = e => { updateList(list.slice(list.indexOf(e.target.name, 1))) } return ( {list.map(item => { return ( <> <span onClick={handleRemoveItem}>x </span> <span>{item.name}</span> </> )} } ) ESPERADO: El elemento en el que se hizo clic se eliminará de la lista.
ACTUAL: se elimina toda la lista, menos el último elemento de la matriz.
¡Gracias por adelantado por cualquier contribución!
En primer lugar, el elemento de span con el evento de clic debe tener una propiedad de name ; de lo contrario, no habrá ningún nombre que encontrar dentro de e.target . Dicho esto, e.target.name está reservado para elementos de formulario (entrada, selección, etc.). Entonces, para aprovechar la propiedad del nombre, tendrá que usar e.target.getAttribute("name")
Además, debido a que tiene una matriz de objetos, no sería efectivo usar list.indexOf(e.target.name) ya que está buscando una string cuando está iterando sobre objetos. Eso es como decir buscar "perro" dentro de [{}, {}, {}]
Por último, array.slice() devuelve una nueva matriz que comienza con el elemento en el índice que le pasó. Entonces, si hizo clic en el último elemento, solo recuperaría el último elemento.
Prueba algo como esto en lugar de usar .filter() : codesandbox
import React, { useState } from "react"; import ReactDOM from "react-dom"; import "./styles.css"; const App = () => { const defaultList = [ { name: "ItemOne" }, { name: "ItemTwo" }, { name: "ItemThree" } ]; const [list, updateList] = useState(defaultList); const handleRemoveItem = (e) => { const name = e.target.getAttribute("name") updateList(list.filter(item => item.name !== name)); }; return ( <div> {list.map(item => { return ( <> <span name={item.name} onClick={handleRemoveItem}> x </span> <span>{item.name}</span> </> ); })} </div> ); }; const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);Puede usar Array.filter para hacer esto en una sola línea:
const handleRemoveItem = name => { updateList(list.filter(item => item.name !== name)) }Eta: también deberá pasar el nombre de su elemento en su controlador onClick:
{list.map(item => { return ( <> <span onClick={() =>handleRemoveItem(item.name)}>x </span> <span>{item.name}</span> </> )}Enfrenté el mismo problema y encontré una solución usando las respuestas a esta pregunta. Estoy poniendo mi solución final aquí porque tuve que usar varias respuestas para llegar allí.
const defaultList = [ { name: "ItemOne" }, { name: "ItemTwo" }, { name: "ItemThree" } ] const [list, updateList] = useState(defaultList); const handleRemoveItem = idx => { // assigning the list to temp variable const temp = [...list]; // removing the element using splice temp.splice(idx, 1); // updating the list updateList(temp); } return ( {list.map((item, idx) => ( <div key={idx}> <button onClick={() => handleRemoveItem(idx)}>x </button> <span>{item.name}</span> </div> ))} )