Реагировать в строгом режиме и двойной рендеринг

Имея такое простое приложение CRA React:

./index.tsx:

import React from 'react';
import ReactDOM from 'react-dom';
import Home from './components/Home';

ReactDOM.render(
  <React.StrictMode>
     <Home></Home>
  </React.StrictMode>,
  document.getElementById('root')
);

./components/Home.tsx:

function Home() {
    let myPromise = new Promise(function(myResolve, myReject) {
        
        let x = 0;
        console.log("--> inside a Promise obj <--");
        
        if (x === 0) {
            myResolve("OK");
        } else {
            myReject("Error");
        }
    }); 

    myPromise.then(
        function(value) {console.log("--> Promise fulfilled <--")},
    );

    return (
        <div>
            <b>Home Page</b>
        </div>
    )
}

export default Home

Я получаю:

--> inside a Promise obj <--
--> Promise fulfilled <--
--> Promise fulfilled <--

на консоли.

Почему выполненный код Promise срабатывает 2 раза? Я знаю, что для режима React Strict компонент визуализируется дважды, но пример показывает некоторую несогласованность - сообщение --> inside a Promise obj <-- вызывается ОДИН раз, а --> Promise fulfilled <-- ДВАЖДЫ! хотя оба сообщения печатаются одной и той же функцией !?


person Daros911    schedule 09.04.2021    source источник


Ответы (1)


Согласно документам: -

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

В качестве временного обходного пути вы можете просто выполнить let log = console.log на верхнем уровне, и тогда он всегда будет регистрироваться.

Получил этот обходной путь от - https://github.com/facebook/react/issues/20090

Вот песочница кода, где вы можете увидеть ожидаемый результат: -

 Изменить ведение журнала в строгом режиме

Ведение журнала внутри then обратного вызова обещания работает, потому что это асинхронное поведение за пределами методов жизненного цикла React. React не заглушает эти журналы в строгом режиме. Но console.log("inside a Promise obj") - это синхронная задача, выполняемая внутри функции Promise исполнителя, которая происходит во время выполнения тела функции вашего компонента.

person Lakshya Thakur    schedule 09.04.2021
comment
Хорошо, спасибо, я знаю это заявление в документации о отключении сообщений журнала. Но если он заглушает --> inside a Promise obj <--, почему он не заглушает --> Promise fulfilled <-- для печати дважды !? Это мой настоящий вопрос, друг! - person Daros911; 09.04.2021