React コンポーネントでは `Promise.then` が 2 回呼び出されるのに、console.log では呼び出されないのはなぜですか? 質問する

React コンポーネントでは `Promise.then` が 2 回呼び出されるのに、console.log では呼び出されないのはなぜですか? 質問する

次のコンポーネントの出力について非常に混乱しています。

import { StrictMode } from "react"
import ReactDOM from "react-dom"

function Test(): React.ReactElement {
    console.log('render')
    Promise.resolve()
        .then(() => console.log('then ' + Math.random()))
    return <></>
}

ReactDOM.render(
  <StrictMode>
    <Test />
  </StrictMode>,
  document.getElementById("root")
)

少なくとも Chrome と Firefox では次の出力が生成されます。

00:46:30.264 render
00:46:30.267 then 0.5430663800781927
00:46:30.267 then 0.9667426372511254

同じ数のメッセージが表示されることを期待します。何が足りないのでしょうか?

再現:https://codesandbox.io/s/elegant-frost-dmcsl

編集: 厳密モードでは追加のレンダリングが必要になることは承知していますが、前述のとおり、メッセージの数は同じになると思います。

編集 2: 以下の回答は両方とも素晴らしいです。ここでは @user56reinstatemonica8 のコメントを引用したいと思います。

関連する:コンソールのサイレント化に関するコミュニティのフィードバック

ベストアンサー1

Reactで厳密モードreactはレンダリングを実行するかもしれない複数何度も繰り返され、それがあなたが見ているものを部分的に説明できるかもしれません。

しかし、あなたは正しく疑問に思ったもしそうならレンダリングが複数回呼び出されたのに、なぜrender2回も印刷されなかったのか?

React は、場合によってはログを無音にするようにコンソール メソッドを変更しますconsole.log()。以下は引用です:

React 17 以降、React は console.log() などのコンソール メソッドを自動的に変更して、ライフサイクル関数の 2 回目の呼び出しでログを無音にします。ただし、回避策を使用できる特定のケースでは、望ましくない動作が発生する可能性があります。

どうやら、Promise コールバックから呼び出される場合はそうならないようですconsole.log。ただし、render から呼び出される場合はそうなります。これについての詳細は、@trincot の回答にあります。

おすすめ記事