为什么组件被重新渲染两次?

时间:2021-06-03 11:47:03

标签: reactjs react-hooks

这是我的 App.js 代码

function App() {
  console.log('Rendering the App  component');
  const [someBooleanVar, updateBooleanVar] = React.useState(false);

    console.log(someBooleanVar);

  const clickHandler = () => {
    console.log('In clickHandler');
    console.log(someBooleanVar);
    updateBooleanVar(true);
  };

  return (
    <div className="app">
      <h1>Test App</h1>
      <button onClick={clickHandler}>Toggle</button>
    </div>
  );
}
    
ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="app"></div>

当页面第一次加载时,我在控制台上看到:

Rendering the App  component
App.js:12 false

现在,当我点击按钮时,控制台显示:

In clickHandler
App.js:16 false
App.js:8 Rendering the App  component
App.js:12 true

如果我第二次点击按钮,控制台会打印:

In clickHandler
App.js:16 true
App.js:8 Rendering the App  component
App.js:12 true

在随后的点击中,这些行被打印出来:

In clickHandler
App.js:16 true

我的问题:第一次点击时,状态已从 false 更新为 true。那么,为什么第二次点击会导致组件被重新渲染,即使状态没有改变?

1 个答案:

答案 0 :(得分:2)

从 Github issue,找到 this 评论

<块引用>

由于 React 中并发的实现细节,这是一个已知的怪癖。我们不知道当前提交了两个版本中的哪一个。当这种歧义发生时,我们必须过度渲染一次,然后我们知道两个版本是相同的,这无关紧要。

所以我们无法帮助有问题的组件,但我们可以帮助孩子们不受影响。

怎么样?

使用React.memo

子组件因此不会受到第二次无用的重新渲染的影响。