使用 useState 钩子的反应组件是否会重新呈现每个 setState 调用?

Does a react component using useState hook rerender every `setState` call?

https://codesandbox.io/s/mow5zl5729

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import axios from "axios";

function useLoading() {
  const [isLoading, setLoading] = React.useState(true);
  const [hasError, setError] = React.useState(false);

  const loadStuff = aPromise => {
    return aPromise
      .then(() => {
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
        setError(true);
      });
  };

  return { isLoading, hasError, loadStuff };
}

function App() {
  const { isLoading, hasError, loadStuff } = useLoading();

  useEffect(() => {
    loadStuff(axios.get(`https://google.com`));
  }, []);

  console.log(isLoading, hasError);

  return <div />;
}

这是我的意思的一个简化示例。

如果 useLoading 中的 promise 被拒绝,我会期望组件在挂载时呈现,然后在捕获到错误时第二次呈现。因此,我预计总共有 2 个具有以下状态的渲染:

第一次渲染:

第二次渲染:

相反,组件似乎在 setLoading(false) 之后重新呈现一次,在 setError(true) 之后再次呈现。所以,我明白了:

第一次渲染:

第二次渲染:(为什么?)

第三次渲染:

我怀疑这个问题不知何故是我在 useEffect 中使用了 promise,但我不确定我的心智模型哪里出了问题。

编辑:

当我将 useLoading 更改为仅包含 1 useState 时,问题就消失了。

损坏:

const [isLoading, setLoading] = React.useState(true);
const [hasError, setError] = React.useState(false);

作品:

const [loadingState, setLoadingState] = React.useState({
  loading: true,
  error: false
});

看起来这与状态更新的批处理有关。据我所知,基于 React 的事件会触发批量更新,但不会触发外部事件。 promise 在这种情况下。

因为状态调用不是批处理的,所以您会看到 2nd render 两者都设置为 false