Вопрос или проблема
Как показать загрузку при смене ключа в useSWR, даже если данные для ключа уже существуют в кэше?
Я использую хук useSWR для получения данных. Я хочу показывать “Загрузка”, всякий раз, когда изменяется ключ. Я включил состояние filter
в ключ useSWR, так что каждый раз, когда состояние обновляется, будет вызвана API.
Например, в интерфейсе, когда я нажимаю на чекбокс “Завершено” (пожалуйста, посмотрите ссылку на площадку), в первый раз значение isLoading
равно true. Затем, если я снимаю отметку и снова ставлю чекбокс “Завершено”, значение isLoading
становится false, потому что данные уже существуют в кэше для того же ключа.
Я знаю, что хук useSWR также предоставляет isValidating
. Я не могу использовать это, потому что я также опрашиваю API каждые 5 секунд. Поэтому, если я использую isValidating
, то в интерфейсе загрузка отображается каждые 5 секунд.
Я хочу показывать “Загрузка”, всякий раз, когда пользователь применяет какой-либо фильтр. Буду признателен за любую помощь.
const [filter, setFilter] = useState({
filterText: '',
showCompleted: false,
});
const { data, error, isLoading, mutate } = useSWR(
['https://jsonplaceholder.typicode.com/todos', filter],
async ([url, filter]) => {
const res = await fetch(`${url}?completed=${filter.showCompleted}`);
return await res.json();
}
);
Площадка – https://stackblitz.com/edit/vitejs-vite-n8hjaa?file=src%2FApp.jsx
Ответ или решение
Для решения проблемы отображения индикатора загрузки при изменении ключа в useSWR
, даже если данные уже существуют в кэше, вы можете использовать состояние для управления индикатором загрузки непосредственно при изменении фильтров. Вот несколько шагов, как это можно реализовать:
-
Создайте локальное состояние загрузки: Используйте
useState
для создания состояния, которое будет контролировать, находится ли приложение в режиме загрузки. -
Управляйте состоянием загрузки при изменения фильтров: При каждом изменении фильтрa устанавливайте состояние загрузки в
true
и возвращайте его вfalse
, когда данные загружены. - Используйте
mutate
для управления кешированными данными: Вы можете использоватьmutate
для обновления состояния загрузки вручную, когда вы хотите показать индикатор загрузки.
Ниже представлен пример кода, который иллюстрирует эти шаги:
import React, { useState, useEffect } from 'react';
import useSWR, { mutate } from 'swr';
const App = () => {
const [filter, setFilter] = useState({
filterText: '',
showCompleted: false,
});
const [isLoading, setIsLoading] = useState(false);
// Функция для фетчинга данных по API
const fetcher = async (url, filter) => {
const res = await fetch(`${url}?completed=${filter.showCompleted}`);
if (!res.ok) {
throw new Error('Ошибка сети');
}
return await res.json();
};
// Используем useSWR для фетчинга данных
const { data, error, isValidating } = useSWR(
['https://jsonplaceholder.typicode.com/todos', filter],
fetcher
);
// Эффект для обработки изменения фильтров
useEffect(() => {
// Устанавливаем индикатор загрузки в true при изменении фильтров
setIsLoading(true);
// Функция для обновления состояния после фетчинга
const fetchData = async () => {
await mutate(['https://jsonplaceholder.typicode.com/todos', filter]);
setIsLoading(false); // Скрываем индикатор загрузки после получения данных
};
fetchData();
}, [filter]); // Эффект вызывается при изменении filter
// Обработка ошибок
if (error) return <div>Ошибка загрузки: {error.message}</div>;
// Показ индикатора загрузки
if (isLoading || isValidating) return <div>Загрузка...</div>;
return (
<div>
<h1>TODO List</h1>
<label>
<input
type="checkbox"
checked={filter.showCompleted}
onChange={(e) => setFilter({ ...filter, showCompleted: e.target.checked })}
/>
Показать завершённые
</label>
<ul>
{data && data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
</div>
);
};
export default App;
В этом коде:
- Мы создаем новое состояние
isLoading
, которое управляет отображением индикатора загрузки. - При изменении фильтров, индикатор загрузки активируется, и в
useEffect
вызывается функцияfetchData
, которая обрабатывает фетчинг данных и отключает индикатор загрузки после завершения процесса. - В компоненте также учитываются ошибки и данные загружаются из кэша, когда это возможно.
Таким образом, вы сможете показывать индикатор загрузки каждый раз, когда пользователь изменяет фильтры, независимо от того, есть ли данные в кэше.