reactjs - 为什么自定义钩子返回结果两次
问题描述
下面的帖子是关于创建一个用于获取数据的自定义钩子,它很简单。
https://dev.to/patrixr/react-writing-a-custom-api-hook-l16
虽然有一部分我不明白它是如何工作的。
为什么这个钩子会返回两次结果?(isLoading=true isLoading=false)
function useAPI(method, ...params) {
// ---- State
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
// ---- API
const fetchData = async () => {
onError(null);
try {
setIsLoading(true);
setData(await APIService[method](...params));
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
useEffect(() => { fetchData() }, []);
return [ data, isLoading, error, fetchData ];
}
function HomeScreen() {
const [ users, isLoading, error, retry ] = useAPI('loadUsers');
// --- Display error
if (error) {
return <ErrorPopup msg={error.message} retryCb={retry}></ErrorPopup>
}
// --- Template
return (
<View>
<LoadingSpinner loading={isLoading}></LoadingSpinner>
{
(users && users.length > 0) &&
<UserList users={users}></UserList>
}
</View>
)
解决方案
React 在事件处理程序和生命周期方法中批量状态更新。
fetchData
不是其中的任何一个,因此不会发生批处理。
现在,调用时fetchData()
:
const fetchData = async () => {
onError(null);
try {
// #1 async setState
setIsLoading(true);
const data = await APIService[method](...params);
// #2 async setState
setData(data);
} catch (e) {
setError(e);
} finally {
// #3 async setState
setIsLoading(false);
}
};
成功时,有3
异步事件,我们只对它感兴趣#1
并且#3
- 将加载状态设置为
true
默认值false
- 将加载状态设置
false
为#1
asyncsetState
。
旁注:乍一看,这个钩子有缺陷,
fetchData
在每次渲染时都会重新分配,你会收到缺少依赖项的警告。
推荐阅读
- node.js - Electron:如何在地址栏上显示 chrome 扩展?
- reactjs - 反应 UI 不更新
- c# - 什么定义了 SVCUTIL 生成的 C# 代理类的运行时版本?
- ruby-on-rails - 无法使用 rails 更新编辑表单中的字段
- php - DataTables关于调整大小的响应问题
- python - 使用 python cv2 捕获外部 USB 网络摄像头的视频(在 Windows 上)
- racket - 获取列表列表的第二个元素作为列表列表
- javascript - AJAX 页面重定向正确。但是由于重定向传递的数据要刷新
- python-3.x - 3d 数组的 Numpy 乘法
- python - 使用每个元素 x 次将 python 数组映射到 x 倍长的数组