Нужно объяснение вывода.Нужно понимать порядок в перехватах и ​​повторных работах - PullRequest
0 голосов
/ 23 мая 2019

Я не могу понять порядок, в котором эффекты и рендеринг работают при наборе вызовов (состояние).Я знаю, что по умолчанию для каждого рендера эффекты гарантированно запускаются.Но в этом случае невозможно применить тот же принцип для соответствия сгенерированному выводу.

function Example() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  console.log("<===rendering===>");

  useEffect(() => {
    console.log("Running Effects")
    Promise.resolve(1)
      .then(() => {
        console.log("BEFORE SET flag", flag);
        setFlag(true);
        console.log("AFTER SET flag", flag);
        console.log("flag4 SET count", count);
        setCount(20);
        console.log("AFTER SET count", count);
      })
  }, [flag, count]);


  return (
    <div>
      Hello
    </div>
  );
}

Вывод

  1. <=== рендеринг ===>
  2. Запущенные эффекты
  3. ПЕРЕД УСТАНОВКОЙ флаг false
  4. <=== рендеринг ===>
  5. ПОСЛЕ УСТАНОВКИ флаг false
  6. ПЕРЕД УСТАНОВКОЙ счетчик 0
  7. Запущенные эффекты
  8. <=== рендеринг ===>
  9. ПОСЛЕ УСТАНОВКИ счетчик 0
  10. ПЕРЕД УСТАНОВКОЙ флаг true
  11. Запущенные эффекты
  12. <=== рендеринг ===>
  13. ПОСЛЕ УСТАНОВКИ флаг true
  14. ПЕРЕД УСТАНОВКОЙ счетчик 0
  15. ПОСЛЕ УСТАНОВКИ счетчик 0
  16. ПЕРЕД УСТАНОВКОЙ флаг true
  17. ПОСЛЕ УСТАНОВКИ флаг true
  18. ПЕРЕД УСТАНОВКОЙ считать 20
  19. ПОСЛЕ УСТАНОВКИ счет 20

1 Ответ

0 голосов
/ 23 мая 2019

Хорошо, вот что происходит: 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» никакой рендеринг не запускается, потому что реагируетсравните новое и предыдущее состояния и может принять решение не отображать.

...