【发布时间】: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