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

442
Vistas
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 Respuestas
Responde la pregunta

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 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