【问题标题】:Why does a simple React Component render twice?为什么一个简单的 React 组件会渲染两次?
【发布时间】:2020-11-22 06:37:19
【问题描述】:

我刚刚开始了一个新的 create-react-app 项目,发现 react 渲染了两次组件!我在 package.json 中的反应版本是 "react": "^16.13.1"

import React, { useRef } from "react";

const App = () => {
  const renders = useRef(0);
  console.log("renders: ", renders.current++);

  return (
    <div>
      Hello
    </div>
  );
};

这会在第一次渲染时产生:

renders: 0
renders: 0

现在如果我添加一个按钮来增加状态,每次状态更改也会产生两个额外的渲染:

import React, { useRef } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const renders = useRef(0);
  console.log("renders: ", renders.current++);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>increment</button>
      <div>count: {count}</div>
    </div>
  );
};

这将导致:

//--- initial render
renders: 0
renders: 0
//--- first click
renders: 1
renders: 2
//--- second click
renders: 3
renders: 4
//--- third click
renders: 5
renders: 6

这是正常的还是最新版本的 react 的 bug?

【问题讨论】:

  • 这是因为严格模式。因此,它将在开发中而不是在生产中运行两次。
  • 是的,经过一些额外的研究,我意识到了这一点。谢谢。

标签: javascript reactjs


【解决方案1】:

好的,看来我找到了原因。检查index.js后发现如下:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

看起来 create-react-app 现在包含 React.StrictMode,它在开发模式(而非生产模式)中双重调用某些方法。

【讨论】:

【解决方案2】:

除了您发现的 StrictMode 问题之外,我认为当您使用 ref 时,它会产生副作用,因此您通常需要将其放入 useEffect 以防止它呈现两次:

import React, { useState, useEffect, useRef } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const renders = useRef(0);
  useEffect(() => {
    // Every time the component has been re-rendered,
    // the counter is incremented
    console.log("renders: ", renders.current++);
  }); 


  return (
    <div>
      <button onClick={() => setCount(count + 1)}>increment</button>
      <div>count: {count}</div>
    </div>
  );
};

export default App;

【讨论】:

    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 2020-09-07
    • 2021-10-21
    • 1970-01-01
    • 2020-01-03
    • 2023-01-24
    • 2022-07-20
    相关资源
    最近更新 更多