在 React 中,为啥子组件的渲染函数会被调用两次?

Posted

技术标签:

【中文标题】在 React 中,为啥子组件的渲染函数会被调用两次?【英文标题】:In React why does a child component's render function get called twice?在 React 中,为什么子组件的渲染函数会被调用两次? 【发布时间】:2020-07-23 02:41:54 【问题描述】:

我有最简单的应用程序。有一个父 <App> 组件和一个子 <MyChildOne> 组件。两者都是基于类的。

谁能解释一下为什么React会两次调用child <MyChildOne>的render函数?

这是我的<App> 代码:

import React from "react";
import "./App.css";
import MyChildOne from "./MyChildOne.js";

class App extends React.Component 
  render() 
    return (
      <div>
        <MyChildOne />
      </div>
    );
  

export default App;

这是我的&lt;MyChildOne&gt; 代码:

import React from "react";

class MyChildOne extends React.Component 
  counter = 0;

  render() 
    this.counter = this.counter + 1;

    console.log(
      "Code has called MyChildOne and this.counter has value: " + this.counter
    );

    return <h1>Hello, this.counter</h1>;
  


export default MyChildOne;

浏览器中的输出是这样的:

你好,1

这是在控制台中记录的内容:

代码调用了 MyChildOne,this.counter 的值为:1

代码调用了 MyChildOne,this.counter 的值为:2

很明显,React 调用了 &lt;MyChildOne&gt; 的渲染函数两次——但我不明白为什么!!!!

这对我没有好处,因为我想将 &lt;App&gt;&lt;MyChildOne&gt; 的一系列事物作为道具传递,并且我希望 &lt;MyChildOne&gt; 为每个“事物”成员呈现一个 &lt;h1&gt;那个数组。我不希望 &lt;h1&gt;s 被渲染两次!

【问题讨论】:

你的代码很好,它调用了一次,也许你渲染了共同的父级。 谢谢你的回答,丹尼斯。 【参考方案1】:

我不知道为什么,但这只会在严格模式下发生。我使用您显示的相同代码创建了一个example project。尝试删除 index.js 文件中的 React.StrictMode 标记。您会看到 MyChildOne 组件只渲染一次。

另外,如果你要在类中设置一个属性并在 render 方法中使用它,你应该使用 state。像这样,

 state = 
     counter: 0
  

。像这样改变状态

this.setState(counter: this.state.counter + 1);

它会正确地重新渲染你的组件。 但是从不改变render方法内部的状态;它会破坏你的代码。

如果您不想使用状态和生命周期方法,请不要使用类组件。改用函数式组件。

【讨论】:

非常感谢,Thet :) 我删除了 标记,子组件现在只呈现一次。他们造成双重渲染似乎很奇怪,但确实如此! @alienCred 在开发构建中,严格模式故意运行一些生命周期方法(包括渲染)额外的时间。这样做是为了暴露由于不安全地使用生命周期方法而导致的错误。 reactjs.org/docs/… 我的荣幸,alienCred【参考方案2】:

您不必太担心渲染函数会被多次调用。如果您创建的逻辑依赖于多次调用的渲染函数,那么您很可能做错了什么。我最好的做法是您正在执行一些导致渲染函数被多次调用的其他逻辑。

您应该注意,如果您的父组件重新渲染,您的子组件也会重新渲染。我创建了您提供的代码的最小示例,这清楚地表明您的问题在其他地方。 https://codesandbox.io/s/react-example-6ud9d

【讨论】:

谢谢你的回答,斯蒂芬 :)

以上是关于在 React 中,为啥子组件的渲染函数会被调用两次?的主要内容,如果未能解决你的问题,请参考以下文章

render()--组件--纯函数

为啥子组件在 React 中没有通过 Axios 获得父组件的 props

React Native组件生命周期

React setState 在调用时渲染组件两次

关于render渲染优化

React Hooks --- useState 和 useEffect