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

346
Vistas
Why does calling the set function of a useState hook apply immediately in async functions?

I experienced different behaviors when calling multiple set functions of a useState hook in sync and async functions.

function Test() {
    console.log('app rendering starts.');
    const [a, setA] = useState(1);
    const [b, setB] = useState(11);
    const updateState = () => {
        console.log('\tupdating a starts.');
        setA(2);
        console.log('\tupdating a ends.');
        console.log('\tupdating b starts.');
        setB(12);
        console.log('\tupdating b ends.');
    };
    console.log('app rendering ends.');
    return (
        <div className="App">
            <div>a is {a}</div>
            <div>b is {b}</div>
            <button onClick={() => {
                console.log('--------------sync click--------------');
                updateState();
            }}>Update State a & b Sync</button>
            <button onClick={() => {
                console.log('--------------async click--------------');
                setTimeout(updateState, 0)
            }}>Update State a & b Async</button>
        </div>
    );
}

Both buttons execute the same code, but in a different way.
Sync button result:

app rendering starts.
app rendering ends.
--------------sync click--------------
    updating a starts.
    updating a ends.
    updating b starts.
    updating b ends.
app rendering starts.
app rendering ends.

Async button result:

app rendering starts.
app rendering ends.
--------------async click--------------
    updating a starts.
app rendering starts.
app rendering ends.
    updating a ends.
    updating b starts.
app rendering starts.
app rendering ends.
    updating b ends.

Is this a desired behavior?
How can I have a sync result in an async function?
I could not find any tips about this in official documents.
Any help would be appreciated.
Thanks!

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

This appears to be a known fact according to Github discussions.

One of the comments, which I thinks is pretty self explanatory:

React currently will batch state updates if they're triggered from within a React-based event, like a button click or input change. It will not batch updates if they're triggered outside of a React event handler, like a setTimeout().

React internally uses unstable_batchedUpdates(). You can pass in a callback function and state updates inside that will be batched. This does not happen automatically for timeouts, promises, and async functions. So they are called from outside the callback and state updates inside them are not batched.

import { unstable_batchedUpdates } from "react-dom";
const updateState = () => {
    unstable_batchedUpdates(() => {
      console.log("\tupdating a starts.");
      setA(2);
      console.log("\tupdating a ends.");
      console.log("\tupdating b starts.");
      setB(12);
      console.log("\tupdating b ends.");
    });
  };

Sandbox Link

about 4 years ago · Juan Pablo Isaza Denunciar

0

You may use single useState() or useReducer() hooks call to update multiple state values by storing them together instead of storing it in separate state slices.

const [values, setValues] = useState({a: 1, b: 11});

setValues({a: 2, b: 12});
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