Estoy creando 50 botones que, al hacer clic, deben establecer el valor useState en el número de botón actual (índice de matriz + 1). Pero me di cuenta de que tengo que hacer clic en un botón dos veces para obtener el valor actual (índice de matriz + 1). El primer clic siempre obtiene el valor del botón en el que se hizo clic anteriormente. Por ejemplo, cuando hice clic en el botón 1 por primera vez, no obtuve nada, cuando hice clic en el botón 2 obtuve 1, cuando hice clic en el botón 3 obtuve 2. Gracias.
Aquí está el código
const [theValue, setTheValue] = useState({first: 1}); const [disableNext, setDisableNext] = useState(false); const [disablePrev, setDisablePrev] = useState(true); <div className="flex flex-row"> {disablePrev ? <div className="flex flex-1 justify-start"> <button type="button" className="btn bg-gray-300 text-gray-400 m-10" disabled>Previous</button></div> : <div className="flex flex-1 justify-start"> <button type="button" className="btn bg-jamb-light-green text-white m-10 hover:bg-green-400" onClick={prevButton}>Previous</button></div>} {disableNext ? <div className="flex flex-1 justify-end"> <button type="button" className="btn bg-gray-300 text-gray-400 m-10" disabled>Next</button></div> : <div className="flex flex-1 justify-end"> <button type="button" className="btn bg-jamb-light-green text-white m-10 hover:bg-green-400" onClick={nextButton}>Next</button></div> } </div> <div> {[...Array(50)].map((item, index) => { return ( <button key={index} className={(index+1 === theValue.first) ? "w-10 h-10 p-2 m-0.5 rounded-full bg-green-500 text-white" : "w-10 p-2 m-0.5 rounded-full bg-red-300 hover:bg-green-400 hover:text-white"} onClick={ () => { if(theValue.first === 1){ setDisablePrev(true); }else if((theValue.first > 1) && (theValue.first < 49)){ setDisablePrev(false); } if(theValue.first === 50){ setDisableNext(true); }else if(theValue.first < 50 && theValue.first > 1){ setDisableNext(false); } setTheValue({...theValue, first: index+1}) } }>{index+1}</button> ) })} </div>Esto se debe a que el estado se establece en el siguiente renderizado. Para actualizar el estado por 1 podrías hacer:
const [theValue, setTheValue] = useState({first: 1}); <div> {[...Array(50)].map((item) =>( <button key={index} className={(index+1 === theValue.first) ? "w-10 h-10 p-2 m-0.5 rounded-full bg-green-500 text-white" : "w-10 p-2 m-0.5 rounded-full bg-red-300 hover:bg-green-400 hover:text-white"} onClick={ () => { setTheValue(currentStateValue => {...currentStateValue, first: currentStateValue.first+1}) } }>{index+1}</button> ) )} </div>En primer lugar, hay un error tipográfico en su segunda condición if, theValue.firts . En cuanto a su problema, cuando actualiza un estado dentro de una función, el estado actualizado no es inmediatamente accesible dentro de la misma función. Solo tiene acceso al valor del estado anterior. Así que digamos que el valor de estado actual es 9 y cuando hace clic en el botón número 10 , está actualizando el valor de estado a 10 y al mismo tiempo registrando en la consola el valor de theValue.first cuyo valor sigue siendo 9 actualmente ya que no tener acceso al valor de estado actualizado de 10 . Ahora, si vuelve a hacer clic en el mismo número de botón, se mostrará 10 , pero no significa que sea el valor de estado actualizado, es el valor de estado que configuró previamente (que es 10 ) cuando hizo clic en el botón. Eso es lo que está pasando allí. Sin embargo, podrá acceder al valor de estado actualizado más reciente dentro del div de procesamiento dentro del párrafo, como he agregado para la demostración a continuación. Siguiendo con su pregunta, el valor del estado se actualiza correctamente. Es solo que el registro de la consola desde la misma función te hace sentir lo contrario.
const [theValue, setTheValue] = useState({ first: 1 }); <div> { [...Array(50)].map((item, index) => { return ( < button key = { index } className = { (index + 1 === theValue.first) ? "w-10 h-10 p-2 m-0.5 rounded-full bg-green-500 text-white" : "w-10 p-2 m-0.5 rounded-full bg-red-300 hover:bg-green-400 hover:text-white" } onClick = { () => { if (theValue.first === 1) { console.log(theValue.first); } else if (theValue.first > 1) { console.log(theValue.first); } if (theValue.first === 50) { console.log(theValue.first); } else if (theValue.first < 50) { console.log(theValue.first); } setTheValue({ ...theValue, first: index + 1 }) } } > { index + 1 } < /button> ) }) } <p>{theValue.first}</p> // access to updated state value </div>