Как использовать setTimeout () вместе с React Hooks useEffect и setState? - PullRequest
0 голосов
/ 20 апреля 2020

Я хочу подождать 10 секунд, пока мой вызов API извлечет массив списка категорий из серверной части и сохранит его в подключенном состоянии. Если за 10 секунд ничего не получается c, я хочу установить состояние перехвата ошибок в значение true.

Но проблема заключается в том, что даже после первоначального извлечения массива состояние ошибки устанавливается равным true, а массив CategoriesList в состояние исчезает через 10 сек c.

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

1 Ответ

1 голос
/ 20 апреля 2020

Проблема в том, что обратный вызов 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

Я рекомендую вам прочитать это сообщение в блоге об использовании эффекта от Дана Абрамова .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...