Установить загрузку с помощью React useEffect не удается

Я пытаюсь показать счетчик загрузки при извлечении данных из API и показать ошибку или результаты после завершения использования useEffect. По какой-то причине isLoading устанавливается в false до завершения выборки.

Не могли бы вы помочь мне, в чем может быть проблема?

const ProblemTable: React.FC<IProblemTableProps> = (props) => {
    // List of problems to show on the table
    const [problems, setProblems] = useState<IProblem[]>([]);

    const [isLoading, setIsLoading] = useState<boolean>(true);
    const [error, setError] = useState<Error>();

    useEffect(() => {
            TierService.getProblems(props.tier, setProblems, setError);
    }, []);

    useEffect(() => {
        setIsLoading(false);
    }, [problems, error]);

    if (isLoading) {
        return <Loading message = "Loading problems..." />;
    }

    if (error) {
        return <ErrorMessage title = "Failed fetching problems" />;
    }

        return <>...</>;


Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

useEffect, который устанавливает загрузку в false, вызывается при монтировании компонента. Добавьте условие, которое превращало бы загрузку в false только после завершения вызова API.

Например, если есть какие-либо проблемы или ошибка, установите загрузку в false:

useEffect(() => {
    if (problems.length || error) setIsLoading(false);
}, [problems, error]);

Однако, если нет проблем или ошибок, loading останется true, поэтому вам, вероятно, понадобится более строгое условие. Лучшим способом было бы установить загрузку на false, если какой-либо из обратных вызовов вызывается:

useEffect(() => {
  TierService.getProblems(
    props.tier,
    p => {
      setProblems(p);
      setLoading(false);
    }
    e => { 
      setError(e);
      setLoading(false);
    }
  );
}, []);

В зависимости от реализации TierService.getProblems второе предложение потерпит неудачу, если обратный вызов не будет вызван, когда ответ пуст.

Я бы, вероятно, создал API на основе Promise, который позволил бы вам использовать async/await с try/catch/finally:

useEffect(() => {
  const api = async () => {
    try {
      const problems = await TierService.getProblems(props.tier);
      setProblems(problems);
    } catch (e) {
      setError(e);
    } finally {
      setLoading(false);
    }
  };

  api();
}, []);

Результатом пустого массива была моя проблема и с вашим первым вариантом. Однако проблема решается установкой isLoading в false при объявлении, а затем в true после вызова службы. И тогда я могу очистить useEffect, вызванный изменениями в проблеме и/или ошибке. Я не знал, что этот useEffect вызывается также при монтировании компонента.

mikovacs 08.02.2023 23:11

Другие вопросы по теме