Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

186
Vistas
React useState updates on click ahead of the desired click

I am creating 50 buttons which on click should set the useState value to the current button number (array index+1). But I realized that I have to click a button twice to get the current value (array index+1). The first click always gets the previously clicked button value. e.g. When I clicked button 1 for the first time, I get nothing, when I clicked button 2 I get 1, when I clicked button 3 I get 2. Thank you.

Here is the code

 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>
about 4 years ago · Santiago Gelvez
2 Respuestas
Responde la pregunta

0

That is because the state is set on the next render. To update the state by 1 you could do:

 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>
about 4 years ago · Santiago Gelvez Denunciar

0

Firstly, there is typo in your second if condition, theValue.firts. Coming to your issue, when you update a state inside a function, the updated state is not immediately accessible inside the same function. You only have access to the previous state value. So let's say, the current state value is 9 and when you click button number 10, you are updating the state value to 10 and at the same time console logging the value of theValue.first whose value is still 9 currently since it doesn't have access to the updated state value of 10. Now if you click the same button number again, it will display 10 but it doesn't mean it is the updated state value, it is the value of state that you previously set(which is 10) when you clicked the button. That's what is going on there. However, you will be able to access the latest updated state value inside the render div inside the paragraph as I have added for demo below. Going with your question, the state value is updated correctly. It's just that console logging from the same function makes you feel otherwise.

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>

about 4 years ago · Santiago Gelvez Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda