Я обнаружил это интересное поведение React, о котором мне хотелось бы узнать больше.
Обычно React отправляет несколько вызовов setState()
внутри обработчика событий, верно?
НоЯ проверял, что React не будет пакетировать вызовы, если:
- Функция обработчика событий - это функция
async
с вызовом await
. - И это
await
вызов выполняет до или между вызовами setState()
. - Если
await
выполняется после вызовов setState()
, они группируются как обычно.
ВОПРОС:
Знаете ли вы, в чем причина этого?
CodeSandbox: https://codesandbox.io/s/eventhandlerawaitso-jsdxs
Это mockAPI
звонок
function mockAPI() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("I come from API using an AWAIT call");
},500);
});
}
Это обработчики для проверки:
function handleClickNormal() {
console.clear();
console.log("Calling 1st setState()");
updateBooleanState(false);
console.log("Calling 2nd setState()");
updateBooleanState(true);
console.log("After 2nd setState()");
}
async function handleClickAwaitBefore() {
console.clear();
// AWAIT CALL RUNS BEFORE THE setState CALLS
const fromAPI = await mockAPI();
console.log(fromAPI);
console.log("Calling 1st setState()");
updateBooleanState(false);
console.log("Calling 2nd setState()");
updateBooleanState(true);
console.log("After 2nd setState()");
}
async function handleClickAwaitAfter() {
console.clear();
console.log("Calling 1st setState()");
updateBooleanState(false);
console.log("Calling 2nd setState()");
updateBooleanState(true);
console.log("After 2nd setState()");
// AWAIT CALL RUNS AFTER THE setState CALLS
const fromAPI = await mockAPI();
console.log(fromAPI);
}
async function handleClickAwaitBetween() {
console.clear();
console.log("Calling 1st setState()");
updateBooleanState(false);
// AWAIT CALL RUNS BETWEEN THE setState CALLS
const fromAPI = await mockAPI();
console.log(fromAPI);
console.log("Calling 2nd setState()");
updateBooleanState(true);
console.log("After 2nd setState()");
}
Вот результат:
Комментарии
Мы можем видеть, что setState()
вызовы группируются, если есть нет await
вызовов (Нажмите Обычный) и если await
вызов приходит после setState()
(Нажмите Ожидание после).
И что setState()
вызовы НЕ пакетируются, если естьawait
звоните до (нажмите "Ожидание до") или между setState()
звоните (нажмите "Ожидание между").