为什么一个简单的React Component渲染两次?

时间:2020-08-01 17:53:50

标签: javascript reactjs

我刚刚启动了一个新的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中的错误?

2 个答案:

答案 0 :(得分:3)

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

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

现在看起来像create-react-app的React.StrictMode可以在开发模式(而不是生产环境)中两次调用某些方法。

答案 1 :(得分:1)

除了您发现的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;
相关问题