React严格模式和双重渲染

React strict mode and double rendering

拥有如此简单的 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 fulfilled 代码被触发了 2 次?我知道,对于 React Strict 模式,组件被渲染了两次,但是示例在这里显示了一些不一致 - --> inside a Promise obj <-- 消息被调用一次,而 --> Promise fulfilled <-- 两次!虽然这两条消息是在同一个函数中打印的!?

根据docs:-

Starting with React 17, React automatically modifies the console methods like console.log() to silence the logs in the second call to lifecycle functions. However, it may cause undesired behavior in certain cases where a workaround can be used.

作为临时解决方法,您可以在顶层执行 let log = console.log,然后它将始终记录。

从 - https://github.com/facebook/react/issues/20090

获得此解决方法

这是一个代码沙箱,您可以在其中看到预期的输出:-

Promise 的 then 回调中的 logging 有效,因为它是 React 的 lifecycle 方法之外的异步行为.在 严格模式 中,React 不会沉默那些 logs。 但是 console.log("inside a Promise obj")Promise 执行器函数内部发生的同步任务,它发生在执行组件的 函数体 .

期间