【问题标题】:Does a react component using useState hook rerender every `setState` call?使用 useState 挂钩的反应组件是否会重新渲染每个“setState”调用?
【发布时间】:2019-08-07 02:17:56
【问题描述】:

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 中的承诺被拒绝,我本来希望组件在挂载时呈现,然后在捕获错误时第二次呈现。所以,我预计总共有 2 个呈现以下状态:

第一次渲染:

  • isLoading: 真
  • hasError: false

第二次渲染:

  • isLoading: 假
  • hasError: true

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

第一次渲染:

  • isLoading: 真
  • hasError: false

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

  • isLoading: 假
  • hasError: false

第三次渲染:

  • isLoading: 假
  • hasError: true

我怀疑问题是我在 useEffect 中使用了承诺,但我不确定我的心智模型哪里出错了。

编辑:

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

坏了:

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

作品:

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

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

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

    由于状态调用未批处理,您会看到 2nd render 两者都设置为 false

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 2020-09-07
    • 2021-04-13
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多