用反作用钩防止倒钩

时间:2020-10-08 10:33:57

标签: javascript reactjs react-hooks

我正在为全局状态实现zustand,但是在设置自己的全局状态时遇到了同样的问题。

将组件连接到简单的useStore挂钩后,每次更新时,组件都会呈现两次。尽管发生了这种情况:

  • 我没有更新任何状态
  • 道具没有改变
  • 为了确定,我将组件包装在React.memo()中
  • 商店中的任何内容(使用zustand创建)都没有改变-除了一项更改应该触发一次更新。

Here's a Codesandbox-一个最小的示例,您可以在其中检查日志-重新加载后和每次更新后,它总是记录两次。对于那些宁愿看到代码却不运行的人:

import React from "react";
import create from "zustand";

const useStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 })
}));

const sessionId = Math.random().toString().slice(2, 7);

const App = React.memo(() => {
  const { bears, increasePopulation } = useStore((state) => state);

  console.log("RENDER Bears", bears, sessionId); // always logs twice
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen.!</h2>
      <button onClick={increasePopulation}>increase</button>
    </div>
  );
});

export default App;

现在,我知道拥有一个额外的渲染并不是一个真正的问题,只是当我的应用增长时,我倾向于将其中的两个组件相互嵌套,以便在我执行想要最小化渲染数量,就很难知道从哪里开始。

所以,我的问题是:

  • 为什么会这样?
  • 我可以防止这种双重渲染吗?如果可以,怎么办?
  • 如果没有,处理此问题的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

这可能是因为您的应用程序包装在React.StrictMode中。 React核心团队表示,双重渲染是有意的。

这是StrictMode的故意功能。这只会发生在 开发,并有助于发现意外的副作用 渲染阶段。我们只对带有挂钩的组件执行此操作,因为 更有可能在错误的地方意外产生副作用。

https://github.com/facebook/react/issues/15074