JavaScript(JS) React 组件中调用两次console.log()但仅执行一次的原因

简介:

本文主要介绍JavaScript(JS) React 组件中,调用两次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")
)

输出信息:

20:44:20.264 render
20:44:30.267 then 0.5430662800781927
40:44:30.267 then 0.9662426372351125

原因:

在React strict模式下,React可以多次运行render,这可以部分解释你所看到的内容。

在某些情况下,React会修改console.log()等控制台方法以使日志静默。

从React 17开始,React会自动修改console.log()等控制台方法,在对生命周期函数的第二次调用中关闭日志。但是,在可以使用解决方案的某些情况下,它可能会导致不希望的行为。

显然,当从Promise回调调用console.log时,它不会这样做。但当从render调用时,它会这样做。

当启用了严格模式(仅在开发模式下)时,会有第二次运行渲染函数,在第二次(同步)运行期间,React 会在第二次(同步)运行期间对console方法(调用disableLogs();)进行monkey patch,因此它不会输出。修改日志输出,这段代码被插入到packages/react-reconciler/src/ReactFiberBeginWork.js中,如下,

if (__DEV__) {
    ReactCurrentOwner.current = workInProgress;
    setIsRendering(true);
    nextChildren = renderWithHooks(
      current,
      workInProgress,
      render,
      nextProps,
      ref,
      renderExpirationTime,
    );
    if (
      debugRenderPhaseSideEffectsForStrictMode &&
      workInProgress.mode & StrictMode
    ) {
      disableLogs();       // <--
      try {                // <--
        nextChildren = renderWithHooks(
          current,
          workInProgress,
          render,
          nextProps,
          ref,
          renderExpirationTime,
        );
      } finally {          // <--
        reenableLogs();    // <--
      }  

了解更多分析及数据抓取可查看:
http://data.yisurvey.com:8989/
特别说明:本文旨在技术交流,请勿将涉及的技术用于非法用途,否则一切后果自负。如果您觉得我们侵犯了您的合法权益,请联系我们予以处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值