Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

208
Vistas
Eliminar todos los elementos de matriz con animación

Tengo una aplicación de lista de tareas nativa de reacción. Los elementos de la tarea están representados por una matriz usando useState que se declara de la siguiente manera:

 const [taskItems, setTaskItems] = useState([]);

Estoy tratando de agregar una función que elimine todos los elementos, pero en lugar de configurarlo así setTaskItems([]) , que simplemente elimina todos los elementos a la vez, esperaba eliminar los elementos uno a la vez a partir del final para crear un aspecto más animado.

 while(taskItems.length > 0) { alert(taskItems.length); let itemsCopy = [...taskItems]; itemsCopy.splice(-1); setTaskItems(itemsCopy); //setTimeout(function(){},180); }

Por alguna razón, el código anterior provoca una recursividad infinita. Si elimino el bucle while, la función deleteAll elimina el último elemento de la lista. Basado en la colocación de la alerta al comienzo de la función, parece que la longitud de la matriz nunca disminuye.

¿Porqué es eso?

¿Y hay una mejor manera de lograr este efecto?

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Sucede porque en su código el valor de taskItem no cambia cuando usa setTaskItems

setTaskItems es una función asíncrona y el valor actualizado de la propiedad de estado cambia después de la representación del componente

puedes intentar algo como esto

 const [taskItems, setTaskItems] = useState([]); const [deleteAll, setDeleteAll] = useState(false) useEffect(() => { if(!deleteAll) return; if(taskItems.lenght === 0){ setDeleteAll(false) return; } setTimeout(() => { setTaskItems(t => t.slice(0, -1)) }, 180) }, [deleteAll, taskItems]) const handleDeleteAll = () => { seDeleteAll(true) }
about 4 years ago · Juan Pablo Isaza Denunciar

0

Esto se debe a que el valor de taskItems se recupera del cierre, lo que significa que no puede esperar que el valor cambie durante la ejecución del controlador. El cierre se recrea solo después de que el elemento se vuelve a representar, lo que significa que puede acceder al nuevo valor de estado solo en la siguiente ejecución de la función; durante la ejecución de la función, el valor del estado nunca cambia.

Solo necesita asignar un valor de longitud a alguna variable temporal y usarla como indicador de inicio/parada para el ciclo while:

 let itemsCount = taskItems.length; while(itemsCount > 0) { // Here use itemsCount to determine how much you would need to slice taskItems array itemsCount -= 1; }

ACTUALIZADO

Una idea de cómo deberías hacerlo es:

 const [items, setItems] = useState([1, 2, 3, 4, 5]); const deleteAll = () => { let counter = items.length; while (counter > 0) { setTimeout(() => { setItems((p) => [...p.slice(0, counter - 1)]); }, counter * 1000); counter -= 1; } };

Es importante multiplicar el retraso del tiempo de espera con la duración, para evitar la ejecución simultánea de todos los tiempos de espera; debe eliminarlos uno por uno. También debe borrar el tiempo de espera al desmontar o algo así.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Debido a la naturaleza asíncrona del enlace useState de React, debe aprovechar useEffect para hacer el trabajo. Aquí hay un ejemplo práctico de cómo eliminar todas las tareas con un retraso de 1000 ms entre elementos.

 function TasksGrid() { const [taskItems, setTaskItems] = useState([1, 2, 3, 4, 5, 6]); const [runDeleteAll, setRunDeleteAll] = useState(false); useEffect( () => { if (runDeleteAll) { if (taskItems.length > 0) setTimeout(() => setTaskItems(taskItems.slice(0, taskItems.length - 1)), 1000); else setRunDeleteAll(false); } }, [runDeleteAll, taskItems] ) const handleOnClick = () => { setRunDeleteAll(true); } return ( <div> {taskItems.map((taskItem, idx) => <p key={idx}>task {taskItem}</p>)} <button onClick={handleOnClick}>delete all</button> </div> ); }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda