Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

262
Views
Javascript: cómo recorrer una matriz una y otra vez en React

Imagina que tengo una serie de objetos como este:

 const items = [ {name: "item 0"}, {name: "item 1"}, {name: "item 2"} ]

Y un componente como este:

 const [currentItemIndex, setCurrentItemIndex] = useState(0) setInterval(function () { if (currentItemIndex < 3) { setCurrentItemIndex(currentItemIndex + 1); } else { clearInterval(); } }, 5000); return ( <div> <p> {items[currentItemIndex].name} <p> </div> )

Quiero actualizar currentItemIndex cada 5 segundos para que el div muestre el siguiente elemento, y si llega al final, debería comenzar de nuevo: 0, 1, 2, 0, 1, 2, 0, 1, 2 ... .

El problema es que se repite correctamente la primera vez, pero después de llegar al final, muestra el primer elemento durante una fracción de segundo y luego pasa al último elemento: 0, 1, 2, 0 (really quick to) 2 .

¿Qué estoy haciendo mal?
Busqué esto, pero todos los artículos hablan de "cómo evitar bucles infinitos", ¡no de "cómo usarlos"!

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Puedes hacerlo con useEffect y con setTimeout así:

 const items = [{ name: "item 0" }, { name: "item 1" }, { name: "item 2" }]; const App = () => { const [currentItemIndex, setCurrentItemIndex] = React.useState(0); React.useEffect(() => { const id = setTimeout( () => setCurrentItemIndex((currentItemIndex + 1) % items.length), 1000 ); return () => { clearInterval(id); // removes React warning when gets unmounted }; }, [currentItemIndex]); return ( <div> <p> {items[currentItemIndex].name} </p> </div> ); }; // export default App; ReactDOM.render(<App />, document.getElementById('root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="root"></div>

about 4 years ago · Juan Pablo Isaza Report

0

Veo algunos problemas con esta lógica que creaste.

En primer lugar, se debe proporcionar a clearInterval una variable que creó al crear la función setInterval (como puede ver aquí ), por lo que clearInterval() no hace nada.

Además de eso, no desea borrar su temporizador cuando currentItemIndex alcanza su umbral, sino que desea que vuelva a cero.

En React, generalmente usamos useEffect para cronometrar eventos, ya que necesita borrarlos al desmontarlos para que no sigan ejecutándose después de desmontar su componente. Algo como esto:

 useEffect(() => { const timer = setInterval(yourFunction); return () => clearInterval(timer); }, [])
about 4 years ago · Juan Pablo Isaza Report

0

Puede utilizar este enfoque si lo desea. Crea una función que establecerá el estado después de 5 segundos usando el tiempo de espera. Una vez que se establece el estado, vuelva a llamar al mismo método. Por el bien de reaccionar, llame a este método una vez usando useEffect.

 import { useEffect, useState } from "react"; const items = [{ name: "item 0" }, { name: "item 1" }, { name: "item 2" }]; export default function App() { const [currentItemIndex, setCurrentItemIndex] = useState(0); useEffect(() => { incrementAfterDelay(1000, 1, 2); }, []); const incrementAfterDelay = (delay, step, lastStep) => { setTimeout( () => setCurrentItemIndex((value) => { return (value < lastStep)? value + step : 0 }, incrementAfterDelay(delay, step, lastStep)), delay ); }; return ( <div> <p> {items[currentItemIndex].name} </p> </div> ); }
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!