为什么console.log 在react js 中记录两次?

HBK*_*396 2 reactjs

我已经开始学习 React,但我无法理解为什么 console.log 会记录两次。下面是我的代码,当我在 chrome 中检查它时,它会显示“随机文本”这个词两次而不是一次。

import React, { Component } from "react";

class Counter extends Component {
  state = {
    count: 0

  };



  render() {
    console.log('random-text');

    return (
      <div>
        <span className={this.getBaadgeClasses()}>{this.formatCount()}</span>
        <button
          onClick={this.handleIncrement}
          className="btn btn-success m-2"
        >
          Increment
        </button>

        {/* <ul>
          {this.state.tags.map((tag) => (
            <li key={tag}>{tag}</li>
          ))}
        </ul> */}
      </div>
    );
  }

  getBaadgeClasses() {
    let classes = "badge m-2 badge-";
    classes += this.state.count === 0 ? "warning" : "primary";
    return classes;
  }

  formatCount() {
    const { count } = this.state;
    return count === 0 ? "Zero" : count;
  }

  handleIncrement = () => {
    this.setState({count: this.state.count + 1})
  }

}

export default Counter;
Run Code Online (Sandbox Code Playgroud)

小智 32

当您创建该项目时,该项目会自动启用严格模式。因此,要解决此问题,请首先index.js在项目中打开文件,然后禁用严格模式。

第1步:当你打开index.js文件时,你会看到类似这样的内容,

root.render(
   <React.StrictMode>
    <App />
   </React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)

步骤2:现在这样做,

root.render(
  // <React.StrictMode>
    <App />
  // </React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)

我希望这能帮到您。谢谢


dav*_*4jr 14

React 团队在严格模式下的双重渲染期间不再静默控制台方法。如果您不想删除严格模式,就像@Florian Motteau提到的那样,那么您可以进入React Dev Tools并选中在严格模式下第二次渲染期间隐藏日志框。请参阅下面的屏幕截图:

在此输入图像描述

以下是 React 团队的引述,以及其 Github 页面上讨论的链接。

在严格模式下,React double 调用渲染方法以消除潜在的副作用。在第二次渲染期间,React 用于自动静音控制台方法(例如 console.log() 和 console.warn()),以减少多个重复日志的噪音。然而,这最终给开发人员在调试过程中带来了很多困惑,因此我们正在改变这种行为。- 反应团队


Dre*_*ese 13

渲染函数是一个生命周期函数,在“渲染阶段”调用

在此处输入图片说明

反应生命周期方法图

请注意,这些函数是纯函数,可以由 React 暂停、中止或重新启动。这意味着 react 可以调用 render 几乎任意次数来协调 virtualDOM 与实际 DOM。

检测意外的副作用

严格模式无法自动为您检测副作用,但它可以通过使它们更具确定性来帮助您发现它们。这是通过有意重复调用以下函数来完成的:

  • 类成分 constructor rendershouldComponentUpdate方法
  • 类组件静态getDerivedStateFromProps方法
  • 函数组件体
  • 状态更新器函数(的第一个参数setState
  • 函数传递给useStateuseMemouseReducer

笔记:

这仅适用于开发模式。生命周期不会在生产模式下被双重调用。

如果你真的想要一个一对一的控制台日志,当组件更新使用其他生命周期函数之一时,就像componentDidUpdate做日志细节的副作用一样。

class Counter extends Component {
  state = {
    count: 0
  };

  componentDidUpdate() {
    console.log("random-text");
  }

  render() {
    return (
      <div>
        <span className={this.getBaadgeClasses()}>{this.formatCount()}</span>
        <button onClick={this.handleIncrement} className="btn btn-success m-2">
          Increment
        </button>

        {/* <ul>
          {this.state.tags.map((tag) => (
            <li key={tag}>{tag}</li>
          ))}
        </ul> */}
      </div>
    );
  }

  getBaadgeClasses() {
    let classes = "badge m-2 badge-";
    classes += this.state.count === 0 ? "warning" : "primary";
    return classes;
  }

  formatCount() {
    const { count } = this.state;
    return count === 0 ? "Zero" : count;
  }

  handleIncrement = () => {
    this.setState({ count: this.state.count + 1 });
  };
}
Run Code Online (Sandbox Code Playgroud)

编辑使用生命周期函数来记录

  • @HBK8396我相信你正在将调用渲染函数(以计算差异)的反应框架与将任何内容提交到DOM混为一谈。阅读“提交阶段”的描述:“可以使用 DOM,*运行副作用*,安排更新”并查看可以执行此操作的生命周期函数。React 遍历整个 virtualDOM 树并在每个组件上调用“render”,*然后*它比较输出,*然后*提​​交差异。即使是呈现静态输出(甚至“null”)的组件也会在协调期间调用其呈现函数。 (2认同)