Reaccionar: Eliminando el primer elemento en el array de useState después de un evento (o temporizador)
Tengo una función que completa una matriz de objetos de useState: coches que aparecen en la parte izquierda de la pantalla y se animan hasta que desaparecen de la pantalla. Después de que el coche desaparezca de la pantalla, quiero que se eliminen de la matriz del estado, para poder tener un bucle infinito de coches aleatorios (a velocidades aleatorias). Los objetos están etiquetados con claves indexadas en 0.
En este momento, estoy intentando un temporizador de 9 segundos para eliminar los coches, pero esto solo vacía toda la matriz después de 9 segundos. ¡Muchas gracias por leer/ayudar!
“`javascript
const getRandomNumber = (min: number, max: number) => {
return Math.random() * (max – min) + min;
};
const getRandomNumberToString = (min: number, max: number) => {
const result = Math.random() * (max – min) + min;
return result.toString();
};
const CarLeft = styled.div<code>animation-duration: ${getRandomNumberToString(2, 9)}s;</code>;
const carListDay = [car1, car2, car3, car4, car5, car6];
function Traffic() {
const [carsOnTheLeft, setCarsOnTheLeft] = useState<any>([]);
const timeout = useRef<any>();
useEffect(() => {
timeout.current = setTimeout(() => {
if (carsOnTheLeft.length < 30)
setCarsOnTheLeft([
…carsOnTheLeft,
<carleft key="{carsOnTheLeft.length}" classname="car__left">
<img src="{carListDay[Math.floor(Math.random()" *="" carlistday.length)]}="" alt="">
</carleft>,
]);
else clearTimeout(timeout.current);
}, getRandomNumber(500, 5000));
console.log(carsOnTheLeft);
<pre><code>setTimeout(() => {
const name = "0";
setCarsOnTheLeft(carsOnTheLeft.filter((item: any) => item.name !== name));
}, 9000);
return () => {
clearTimeout(timeout.current);
};
</code></pre>
}, [carsOnTheLeft]);
return
<div classname="traffic__container">{carsOnTheLeft}</div>
;
}
export default Traffic;
“`
davy.ai
Para eliminar los autos que se han salido de la pantalla del array
useState
, puedes agregar un efecto (useEffect
) con una función de limpieza que elimine los autos en función de su posición.En primer lugar, necesitarías agregar una variable de estado para llevar un seguimiento de las posiciones de los autos:
const [carPositions, setCarPositions] = useState<any>([]);
Esta variable será un arreglo de objetos que contiene la posición de cada auto. Cuando se agrega un auto al arreglo
carsOnTheLeft
, puedes agregar un objeto de posición correspondiente acarPositions
:Aquí, la clave (
key
) corresponde a la clave del auto en el arreglocarsOnTheLeft
yposition
representa la posición actual del auto.Para actualizar la posición de los autos, puedes agregar un
setTimeout
dentro del efecto (useEffect
) que actualice la variableposition
de cada objeto de posición de auto:Aquí, se agrega la función
onAnimationEnd
a cada elemento de auto. Cuando la animación termine, esta función eliminará el auto correspondiente y su posición del arreglo respectivo filtrándolos por la clave.Ahora, puedes agregar otro efecto (
useEffect
) que verifique si algún auto se ha salido de la pantalla y lo elimine de los arregloscarsOnTheLeft
ycarPositions
:Aquí, el arreglo
carPositions
se filtra en función de la condición de que la posición sea mayor quewindow.innerWidth
, que representa el ancho de la pantalla. Si un objeto de posición no cumple esta condición, se eliminará el auto correspondiente del arreglocarsOnTheLeft
y se eliminará el objeto de posición del arreglocarPositions
.Por último, puedes eliminar el temporizador de 9 segundos para eliminar todos los autos y mantener el efecto (
useEffect
) que elimina los autos en función de su posición:Con estos cambios, tendrás un bucle infinito de autos aleatorios que se mueven por la pantalla a velocidades aleatorias y se eliminan cuando salen de la pantalla.