javascript - 如何将 setTimeout() 与 React Hooks useEffect 和 setState 一起使用?
问题描述
我想等待 10 秒,让我的 API 调用从后端获取类别列表数组并以挂钩状态存储。如果在 10 秒内没有获取任何内容,我想将错误挂钩状态设置为 true。
但问题是,即使在最初获取数组之后,错误状态设置为 true,并且状态中的 categoriesList 数组在 10 秒后空白。
import React, { useState, useEffect } from "react";
import { doGetAllCategories } from "../helper/adminapicall.js";
const ViewCategories = () => {
let [values, setValues] = useState({
categoriesList: "",
error: false,
});
let { categoriesList, error } = values;
const preloadCategories = () => {
doGetAllCategories()
.then((data) => {
if (data.error) {
return console.log("from preload call data - ", data.error);
}
setValues({ ...values, categoriesList: data.categories });
})
.catch((err) => {
console.log("from preload - ", err);
});
};
useEffect(() => {
preloadCategories();
let timerFunc = setTimeout(() => {
if (!categoriesList && !error) {
setValues({
...values,
error: "Error fetching category list... try after some time !",
});
}
}, 10000);
return () => {
clearTimeout(timerFunc);
};
}, []);
//...further code
解决方案
问题是useEffect
回调是一个闭包categoriesList
,因此您将始终在回调中看到初始类别列表,而您不会看到对其进行任何更改。现在可以将categoriesList
依赖项添加到useEffect
挂钩中,这样每次categoriesList
更改都会重新创建挂钩,因此您可以看到更改后的版本:
useEffect(/*...*/, [categoriesList]);
现在好消息是,通过更新钩子,超时也会被取消,所以如果设置了类别列表,我们就不必创建新的超时:
useEffect(() => {
if(!categoriesList && !error) {
let timerFunc = setTimeout(() => {
setValues({
...values,
error: "Error fetching category list... try after some time !",
});
}, 10000);
return () => clearTimeout(timerFunc);
}
}, [!categoriesList, !error]); // some minor optimization, changes to the list don't bother this hook
推荐阅读
- java - 全局布尔值在 addListenerForSingleEventValue 函数中设置,但在以下 if 语句中无法识别
- java - 将数组与文本文件进行比较
- r - 使用 R 中的 httr 包通过 HTTP 请求访问 Moodle (Gradebook) API
- python - 尝试更改外部函数中的类变量时出现 NameError
- android - Recyclerview onCreateViewHolder 没有调用
- database - 缩小 RDS 实例上的 pg_toast
- javascript - addEventListener('popstate') 在 IE 11 中不起作用
- python - 使用 Panda 拆分(“提取”)列
- docker - 通过 nginx 在 docker 容器中部署应用程序时出现 403 禁止错误
- sql - 拆分字符串的 SQL Server 替代方法