Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

181
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda