Автоматическое обновление данных с refetchInterval
Автоматическое обновление данных полезно в тех случаях, когда у вас есть динамические данные, которые часто изменяются, например, данные с сервера в реальном времени: курсы валют, статистика или метрики серверов.
React Query предоставляет свойство refetchInterval, с помощью которого можно настроить периодическое обновление данных.
Пример: автоматическая загрузка данных о погоде
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
interface WeatherData {
city: string;
temperature: number;
}
const fetchWeather = async (): Promise<WeatherData> => {
const { data } = await axios.get('https://api.example.com/weather');
return data;
};
const WeatherComponent = () => {
const { data, isLoading, isError } = useQuery<WeatherData>({
queryKey: ['weather'],
queryFn: fetchWeather,
refetchInterval: 10000, // Обновление каждые 10 секунд
});
if (isLoading) return <p>Загрузка...</p>;
if (isError) return <p>Ошибка при загрузке данных</p>;
return (
<div>
<h1>Погода</h1>
<p>Город: {data?.city}</p>
<p>Температура: {data?.temperature}°C</p>
</div>
);
};
export default WeatherComponent;
Что здесь происходит?
refetchInterval: 10000— React Query автоматически выполняет новый запрос каждые 10 секунд.- Даже если вы не обновляете компонент, данные будут постоянно обновляться в фоне. Удобно, правда?
Особенности refetchInterval
- Значение интервала указывается в миллисекундах.
- Можно задать
refetchInterval: false, чтобы отключить автообновление. - Не злоупотребляйте чрезмерно короткими интервалами, если ваш сервер этого не выдержит. Ваш DevOps-коллега вам спасибо не скажет.
Обновление при смене фокуса: refetchOnWindowFocus
Когда вы возвращаетесь в браузерную вкладку вашего приложения, было бы неплохо автоматически обновить устаревшие данные. Здесь в дело вступает настройка refetchOnWindowFocus.
Пример: обновление данных после переключения вкладок
const { data, isLoading, refetch } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUserData(userId),
refetchOnWindowFocus: true, // Обновляется автоматически при фокусе
});
Как это работает?
React Query отслеживает, когда пользователь возвращается к приложению (например, после переключения вкладок), и инициирует refetch, если данные устарели.
А что если отключить?
Вы можете задать параметр refetchOnWindowFocus: false, если не хотите автоматического обновления при смене фокуса. Например, в случае, если запросы к API дорогие или данные редко меняются.
Ручное обновление данных: вызов refetch
Автоматизация — это круто, но иногда вам нужно больше контроля. Предположим, вы построили погодное приложение, где есть кнопка для ручного обновления данных. Здесь на помощь приходит метод refetch.
Пример: кнопка для ручного обновления
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
interface WeatherData {
city: string;
temperature: number;
}
const fetchWeather = async (): Promise<WeatherData> => {
const { data } = await axios.get('https://api.example.com/weather');
return data;
};
const WeatherComponent = () => {
const { data, isLoading, isFetching, refetch } = useQuery({
queryKey: ['weather'],
queryFn: fetchWeather,
refetchOnWindowFocus: false, // Отключаем автоматическое обновление
});
return (
<div>
{isLoading ? (
<p>Загрузка...</p>
) : (
<>
<h1>Город: {data?.city}</h1>
<h2>Температура: {data?.temperature}°C</h2>
</>
)}
<button onClick={() => refetch()} disabled={isFetching}>
{isFetching ? 'Обновление...' : 'Обновить'}
</button>
</div>
);
};
export default WeatherComponent;
Что здесь нового?
- Метод
refetchвызывается при клике на кнопку, инициируя новый запрос. isFetchingпомогает отобразить состояние загрузки данных повторно.
Управление частотой запросов
Слишком частые запросы могут перегрузить ваш сервер и истощить лимиты API. React Query позволяет отрегулировать частоту обновлений с помощью staleTime (время, в течение которого данные считаются актуальными) или cacheTime.
Пример: настройка staleTime и cacheTime
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
interface WeatherData {
city: string;
temperature: number;
}
const fetchWeather = async (): Promise<WeatherData> => {
const { data } = await axios.get('https://api.example.com/weather');
return data;
};
const WeatherComponent = () => {
const { data } = useQuery({
queryKey: ['weather'],
queryFn: fetchWeather,
staleTime: 30000, // Данные свежие 30 секунд
cacheTime: 60000, // Кэш хранится 1 минуту
});
return (
<div>
<h1>Погода</h1>
<p>Город: {data?.city}</p>
<p>Температура: {data?.temperature}°C</p>
</div>
);
};
Что делают эти опции?
staleTime: если данные считаются актуальными (не устарели), новый запрос не будет выполнен.cacheTime: после истечения этого времени кэшированные данные удаляются из памяти.
Автоматическое обновление на восстановление подключения с refetchOnReconnect
Интернет-соединение иногда исчезает, словно ваш код после git reset --hard. Когда соединение восстанавливается, React Query может автоматически обновить данные.
Пример: обновление данных после восстановления соединения
const ExchangeRatesComponent = () => {
const { data, isLoading } = useQuery({
queryKey: ['exchangeRates'],
queryFn: fetchExchangeRates,
refetchOnReconnect: true, // Автоматическое обновление при повторном подключении
});
if (isLoading) return <p>Загрузка курсов валют...</p>;
return (
<div>
<h1>Курсы валют</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
Типичные ошибки при обновлении данных
В работе с refetch и автообновлением могут возникать проблемы:
Слишком частые запросы: использование маленьких значений
refetchIntervalможет перегрузить ваш сервер. Всегда проверяйте свои ограничения API.Ошибки синхронизации данных: если данные на сервере обновляются реже, чем ваш
refetchInterval, вы просто истощите ресурсы без пользы.Отсутствие проверки соединения: в случае отсутствия подключения ваш клиент может "зависнуть" в ожидании данных. Настройка
refetchOnReconnectможет помочь в таких случаях.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ