Hay una lista de 5 elementos. Por defecto, la lista (matriz) debe mostrar ["A", "B", "C", "D", "E"]. Cada segundo los elementos deben rotar una posición:
Lista después de 1 segundo: ["B", "C", "D", "E", "A"];
Después de 2 segundos: ["C", "D", "E", "A", "B"];
Después de 3 segundos: ["D", "E", "A", "B", "C"];
Estoy aprendiendo y necesito ayuda. Como resolverías este problema? Esta es mi solución incorrecta:
import React, { useState, useEffect } from "react"; import "./App.css"; function App() { const [term, setTerm] = useState(); const [letter, setLetter] = useState([]); let array = ["A", "B", "C", "D", "E"]; useEffect(() => { const interval = () => setInterval(() => { array.push(array.shift()); setLetter(array); }, 1000); interval(); return clearInterval(interval); }, [array]); return ( <div className="center"> <input type="text" value={term} onChange={(e) => setTerm(e.target.value)} /> {letter && letter.map((l, i) => { return ( <ul key={l}> <li>{l[0]}</li> <li>{l[1]}</li> <li>{l[1]}</li> <li>{l[3]}</li> <li>{l[4]}</li> </ul> ); })} </div> ); } export default App;Solo soy un aprendiz, estoy atascado y necesito ayuda. Cambia rápidamente, como cada 50ms.
Analizaré la respuesta y aprenderé de ella porque no puedo hacerlo solo.
Lo que sucede aquí es que tiene un useEffect de uso adjunto a los cambios de array que cambia varias veces dentro de la devolución de llamada del intervalo.
useEffect () -> Activa el efecto de usouseEffectEsto se agrava y comienza a cambiar la matriz rápidamente.
Sugeriría trabajar con una copia de matriz o algo por el estilo.
setInterval(() => let copy = […array]; copy.push(copy.shift()); setLetter(copy); array = copy }, 1000); Solo otra sugerencia. También intentaría no usar la variable de array adicional ya que esos datos ya están almacenados en la letter . Así es como yo haría esto.
const [letter, setLetter] = useState(["A", "B", "C", "D", "E"]); useEffect(() => { setTimeout(() => let copy = […letter]; copy.push(copy.shift()); setLetter(copy); }, 1000); }, [letter]);No probé esto, así que espero que ayude.
Le sugiero que evite modificar su matriz. En lugar de usar push y shift , genere una nueva versión de la matriz mediante arr => [...arr .slice (1), arr [0]] o usando concat :
const {useState, useEffect} = React; const App = () => { const [letters, setLetters] = useState (["A", "B", "C", "D", "E"]) useEffect(() => { const timer = setTimeout ( () => setLetters (arr => arr .slice (1) .concat (arr [0])), 1000 ) return () => clearTimeout (timer) }) return (<div>{letters .join (' ')}</div>) } ReactDOM .render (<App/>, document .getElementById ("main")) <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="main"></div>La modificación de datos solo a través del setter hace que las cosas sean mucho más consistentes.
Tenga en cuenta que esto funcionará bien sin devolver clearTimeout , pero probablemente sea un buen hábito.