Actualmente estoy tratando de enseñarme a mí mismo a reaccionar. Me encontré con este comportamiento extraño y no podía explicar lo que estaba pasando, así que esperaba obtener algunas respuestas.
En el siguiente fragmento de código. Tengo un index
variable que inicialmente se establece en 0
. Cuando hago clic en el botón, espero que handleClick()
actualice el valor de index
. Sin embargo, no lo hace como yo esperaría.
const { useState } = React; const Home = () => { let names = ["Hello", "World"]; let index = 0; const [name, setName] = useState(names[index]); const handleClick = () => { console.log(`Output: ${name}`); console.log(`Index = ${index}`); index = (index+1)%2; setName(names[index]); } return ( <div className="Home"> <button onClick={handleClick}>Click</button> </div> ); } ReactDOM.render(<Home />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
Espero que la salida de console.log
sea la siguiente:
Output: Hello Index = 0 Output: World Index = 1 Output: Hello Index = 0 Output: World Index = 1 ...
En cambio, lo que obtengo es:
Output: Hello Index = 0 Output: World Index = 0 Output: World Index = 1 Output: Hello Index = 0 ...
¿Alguien puede explicar qué está pasando aquí?
Cuando una variable de estado se actualiza mediante el método setState, el componente se vuelve a representar. En su código, la variable de índice no es una variable de estado, por lo que cada vez que el componente Inicio se vuelve a representar, la variable de índice se inicializará en 0.
Puede cambiar el índice a la variable de estado o también puede usar ref, si desea conservar su estado en las re-renderizaciones.
Debería considerar mover el índice al estado y mover los nombres a los accesorios. El primero corregirá el comportamiento del componente, como está buscando, y el segundo hará que el componente sea más reutilizable.
const { useState } = React; const Home = ({names}) => { const [index, setIndex] = useState(0); const name = names[index]; const handleClick = () => { console.log(`Output: ${name}`); console.log(`Index = ${index}`); setIndex((index+1)%2); } return ( <div className="Home"> <button onClick={handleClick}>Click</button> </div> ); } ReactDOM.render(<Home names={["Hello", "World"]} />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
en lugar de let index = 0
que se reinicializa a 0 cada vez que se ejecuta setName
, necesita algo que no se reinicializa, como se muestra a continuación
//on your imports import {useRef} from 'react' //inside you component const index = useRef(0); //on updating it index.current = (index.current+1)%2