如何将 setTimeout() 与 React Hooks useEffect 和 setState 一起使用?

Suy*_*kar 4 javascript settimeout reactjs react-hooks use-effect

我想等待 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
Run Code Online (Sandbox Code Playgroud)

Jon*_*lms 9

问题是useEffect回调是对 的闭包categoriesList,因此您将始终在回调内看到初始类别列表,并且不会看到对其进行任何更改。现在可以将categoriesList依赖项添加到useEffect挂钩,这样每次categoriesList更改都会重新创建挂钩,因此您可以看到更改后的版本:

useEffect(/*...*/, [categoriesList]);
Run Code Online (Sandbox Code Playgroud)

现在好的事情是,通过更新钩子,超时也被取消,所以如果设置了类别列表,我们就不必创建新的超时:

  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
Run Code Online (Sandbox Code Playgroud)

我建议您阅读Dan Abramov 撰写的关于 useEffect 的博客文章