组件是否渲染了两次?是codesandbox问题吗?

Is component rendered twice? Is it codesandbox problem?

这是我的简单 React 应用程序:

let idCounter = 0;

export default function App() {
  const id = useMemo(() => {
    console.log("useMemo");
    return idCounter++;
  }, []);

  console.log("render", id);

  useEffect(() => {
    console.log("useEffect", id);
  });

  return id;
}

https://codesandbox.io/s/morning-bush-swky8

这是控制台输出:

useMemo
render 0
useEffect 1

为什么在useEffectid等于1?

好像组件渲染了两次,但是为什么useMemouseEffect没有被调用到第二次呢? id 是如何变成 1?

来自React Docs - Strict Mode:

Starting with React 17, React automatically modifies the console methods like console.log() to silence the logs in the second call to lifecycle functions. However, it may cause undesired behavior in certain cases where a workaround can be used.

您的组件确实被渲染了两次,但是在 StrictMode.

引起的第二次重新渲染期间,React 隐藏了日志语句

如果删除 StrictMode.

,您将获得预期的输出

另一种选择是在 console 对象上使用不同的方法进行日志记录,例如 console.dir.

let idCounter = 0;

function App() {
  const id = React.useMemo(() => {
    console.dir("useMemo");
    return idCounter++;
  }, []);

  console.dir("render");
  console.dir(id);

  React.useEffect(() => {
    console.log("useEffect", id);
  });

  return id;
}

ReactDOM.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>, 
  document.querySelector("#root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.min.js"></script>

<div id="root"></div>