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

452
Visualizações
React Hooks `useState` set function exhibits sync as well as async behaviour

Consider a button callback listener in React Functional components defined as below -

Here's the codesandbox link to repro this.

const [setCtr, ctr] = useState(0);
const btnClicked = () => {
    console.log("button callback");
    setCtr((x) => {
      console.log("setCtr executed...");
      return x + 1;
    });
    console.log("button callback ends");
  };

When I click on the button, the first time, setCtr executes synchronously but after that it always (tried 20 times) runs asynchronously.

Here's the output for first button click

button callback 
setCtr executed... 
button callback ends 

Here's the output for subsequent button clicks

button callback 
button callback ends 
setCtr executed... 

button callback 
button callback ends 
setCtr executed... 

button callback 
button callback ends 
setCtr executed... 

button callback 
button callback ends 
setCtr executed... 

This is confusing. How exactly does the set function in useState work? If it was truly an async function, we should always get button callback ends before setCtr executed....
This makes me think sometimes it behaves as synchronous function, while sometimes as asynchronous function.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

This statement is not totally true: If it was truly an async function, we should always get button callback ends before setCtr executed.... React 18 batches all setStates, but it has also a priority queue for every instruction that you write inside handlers, synchronous or asynchronous, so you should not rely on the callback of the setState to happen before or after something else, unless you explicitely say to React to execute it synchronously:

function App() {
  const [ctr, setCtr] = React.useState(0);
  const btnClicked = () => {
    console.log("button callback", ctr);
    ReactDOM.flushSync(() =>
      setCtr((x) => {
        console.log("setCtr executed...",x);
        return x + 1;
      })
    );
    console.log("button callback ends", ctr);
  };
  console.log("RERENDERING X:", ctr)
  return (
    <div className="App">
      {ctr}
      <br />
      <button onClick={btnClicked}>Add</button>
    </div>
  );
}

ReactDOM.render(<App/>, root)
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

React, especially React 18 applies some heavy code optimizations so don't think it just executes the code you write inside handlers "as is". As you can see, using flushSync explicitely tells React to flush all the setStates immediately when invoked, so it stops all synchronous code inside the handler, re-renders the component, and then keeps executing the rest of the code. You can note, that the state of the last log is stale when it gets executed, and it refers to the previous value, since the instruction was memoized on the value of the state at the time you declared it. That's another important feature of React. That's why you should always rely on Hooks like useEffect or useMemo with the deps that you are interested to track, to perform operations after the state updated.

Reference: https://reactjs.org/docs/react-dom.html#flushsync

about 4 years ago · Juan Pablo Isaza 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