Хорошо, вот что происходит: Promise.resolve().then
в основном ставит в очередь выполнение блока then после фазы эффектов, поэтому в этом случае setState
s запускают новый рендеринг немедленно, затем, до следующегоEffects начинает выполнение блока then.
Я немного изменил ваш код, чтобы лучше понять, что console.log принадлежит каждому рендеру.
https://codesandbox.io/s/weathered-lake-heh9j
Первый рендеринг начинается
#1 "<===rendering===>" false 0
Первый рендеринг заканчивается рендерингом
Первый рендеринг начинается с эффектов
#1 "Running Effects" false 0
первый эффект рендеринга end
первый рендер Promise.then начинается блок
#1 "BEFORE SET flag" false 0
первый рендер setCount немедленно вызывает nextрендеринг, потому что мы уже закончили с фазой эффекта секунда рендеринга начинается
#2 "<===rendering===>" true 0
секунда рендеринга заканчивается рендерингом
Первый рендер Promise.then блок продолжается
#1 "AFTER SET flag" false 0
#1 "BEFORE SET count" false 0
fiПервый рендеринг setCount немедленно вызывает третий рендеринг, потому что мы уже закончили с фазой эффекта, но перед реакцией рендеринга второй ожидающий эффект рендеринга
второй эффект рендеринга начинает
#2 "Running Effects" true 0
второй эффект рендеринга заканчивается
третий рендеринг начинается
#3 "<===rendering===>" true 20
третий рендеринг заканчивается рендерингом
первый рендеринг Promise.then блок продолжается
#1 "AFTER SET count" false 0
первый рендеринг Promise.then заканчивается блок => первый рендеринг все сделано
второй рендеринг Блок Promise.then начинается
#2 "BEFORE SET flag" true 0
второй рендер setCount немедленно вызывает четвертый рендер, потому что мы уже закончили с фазой эффекта, но до рендера,реагирует ли третий рендер ожидающие эффекты
третий эффект рендеринга начинается
#3 "Running Effects" true 20
третий эффект рендеринга заканчивается
начинается четвертый рендер
#4 "<===rendering===>" true 20
четвертый повторnder заканчивается, не имеет эффектов, потому что количество и флаг не изменились
второй рендеринг Promise.then блок продолжается
#2 "AFTER SET flag" true 0
#2 "BEFORE SET count" true 0
#2 "AFTER SET count" true 0
второй рендерингPromise.then заканчивается блок
третий рендер Promise.then начинается
#3 "BEFORE SET flag" true 20
#3 "AFTER SET flag" true 20
#3 "BEFORE SET count" true 20
#3 "AFTER SET count" true 20
третий рендер Promise.then заканчивается блок
следующий модифицированный пример может помочь понять, что происходит с реакцией.
https://codesandbox.io/s/competent-wozniak-syr0s
обратите внимание, что при нажатии кнопки «Установить флаг true» никакой рендеринг не запускается, потому что реагируетсравните новое и предыдущее состояния и может принять решение не отображать.