【问题标题】:Why does React re-renders children when props does not change?为什么当 props 没有改变时 React 会重新渲染孩子?
【发布时间】:2021-05-03 12:55:51
【问题描述】:

考虑以下示例:

import "./styles.css";
import React from "react";

function Children(props) {
  const counter = props.counter2;
  console.log("re-rendering children");
  return (
    <div className="App">
      <p>counter2 value = {counter} </p>
    </div>
  );
}

export default function App() {
  const [counter, setCounter] = React.useState(0);
  const [counter2] = React.useState(0);
  return (
    <div className="App">
      <p>counter value = {counter} </p>
      <button onClick={(e) => setCounter((c) => c + 1)}>increment</button>
      <Children counter2={counter2} />
    </div>
  );
}

Children 组件不依赖父状态counter,但是当我点击按钮时,我可以看到每次点击都会打印re-rendering 日志。如果我没记错的话,这意味着 Children 组件被重新渲染。我的问题是为什么?它不应该重新渲染,因为道具没有改变。

代码沙箱:https://codesandbox.io/s/modern-dawn-xj9b8

【问题讨论】:

  • 因为默认情况下重新渲染的组件的所有子组件都会重新渲染。要防止子组件重新渲染,请考虑使用React.memo
  • 在同一个地方找到了一个优秀的article :)

标签: javascript reactjs typescript


【解决方案1】:

因为 React 的生命周期,当你在使用一个函数式组件时,它也被认为是无状态的,每次它的父组件有更新时都会重新渲染,无论传入子组件的 props 是否有变化.

有两种方法可以改变这种行为,

  1. 使用类组件并决定是否使用shouldComponentUpdate更新它

  2. 或使用React.memo的推荐方式,

import "./styles.css";
import React from "react";

function Children(props) {
  const counter = props.counter2;
  console.log("re-rendering children");
  return (
    <div className="App">
      <p>counter2 value = {counter} </p>
    </div>
  );
}

const MemoChild = React.memo(Children);

export default function App() {
  const [counter, setCounter] = React.useState(0);
  const [counter2] = React.useState(0);
  return (
    <div className="App">
      <p>counter value = {counter} </p>
      <button onClick={(e) => setCounter((c) => c + 1)}>increment</button>
      <MemoChild counter2={counter2} />
      {/* <Children counter2={counter2} /> */}
    </div>
  );
}

docsReact.memo 的更多信息

如果您的组件在给定相同的 props 的情况下呈现相同的结果,您可以将其包装在对 React.memo 的调用中,以便在某些情况下通过记忆结果来提高性能。这意味着 React 将跳过渲染组件,并重用上次渲染的结果。

【讨论】:

    【解决方案2】:

    这个答案是正确的,您可以使用 React.memo,但在开始使用之前,请查看一些文章以确定何时使用它是有价值的。 使用不当可能会损害您的表现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-12
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      相关资源
      最近更新 更多