Як React Query скасав 500 ліній у шары API даплы React Native
Рэальны прыклад з выкарыстоўванням React Native, який паказвае, як пераход з ручнага запрашання дадзейнаў за дапамою useEffect на React Query парадукаў павтаральны код і паспячыў паўработці кэшу і лепшай роботы без падключення да Інтэрнету.
Введэнне
Ёсць час тады, калі кодбаза React Native, якую вы можаце атрымліваць, сталкалася з вядомай проблемай.
Практычна кожны экран, які патрэбаваў даўнейшых дадзенаў, выконваўся за аднаковым прыемам:
- Запыты на запрашэнне дадзенаў, распакаваныя ўнутрь
useEffect - Калькі разлучных флажоў загрузкі
- Спецыяльныя блакі для обработкі адзінакоў
- Логіка апцэнкі, створаная вручную
- Механізмы рэпрытавання дзеянняў
- Тымчасовыя способы кэшавання дадзенаў
З функцыональнага точка зору нічога з гэтага не было сломана. Але падтрымка аднаковасці ў дзесятках экранаў стала сэрьёзным трыбутам для тыхоўкі.
Пераход на React Query (з TanStack) дазволіў командазьліць велику кантэнт павтараючыся коду для працы з сетью, а ў вярненне — кращую кэшавання, аднаціснейшае керуванне процесам загрузкі та болей надзеяныю роботу па безсетевым режыме. Шаблон бібліятэкі включае в сябе вбудована кэшавання запытак, аўтаматычнае падтрымканне данных у фонавым режыме та логіку, якая врачуе аспекты сеті, чым зменшае потрэбу самастайна пісаць механізмы керування станам.
Далей паказана поручнае прадстаўленне старага ручнага падходу прырэшта версіі React Query, на прыкладзе патэранаў з рэальных экранаў React Native у прымененні.
Проблемы з традыцыйным керуванням API
Настройка типовага экрана выглядала прыблізна так:
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [refreshing, setRefreshing] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
try {
setLoading(true);
const response = await api.getPosts();
setData(response);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
Этот жа шаблон павтараўся знову і знову ў всім прымененні.
Кожны экран патрабаваў незалежна керуваць:
- Флагам загрузкі
- Флагам адказу пра аберанне
- Механізамом павторной спробы
Калі додатак продовжваў растаць, гэты павтараючыся шаблон стаў усё складнейшым для падтрымкі ўніверсальнасці.
Праявляе ся React Query
Тая ж экран, перапісаны з вядомаю дапамогай React Query, спраўдзіўся такім:
const { data, isLoading, error, refetch } = useQuery({
queryKey: ["posts"],
queryFn: fetchPosts,
});
Гэта ўсё рэалізаванне.
React Query аўтаматычна керуе всім наступным:
- Індыкаторы загрузкі
- Станы абяканняў
- Усуненне дублікаў ідэнтычных запытак у процесе
- Перазапытка дадзеных у фоне
- Керуванне кэшам
- Прабавы зноў выканаць неудачныя запыткі
- Реакцыя на паўторную наладку сеті
Большая частка гэтых функцыяй доступна без дапамогі дадатковых налаштаванняў, і ўсё гэта можна налаштаваць за дапамогою такіх параметраў, як staleTime, gcTime, настройкі прабав і параметры перазапытку.
Порэванаўненне #1: Запыты сеті
Да React Query
Уявіце тры разныя экраны, якім усім патрэбны тыя ж данні пра профіль пользователя.
Без якога-лібо спяльнага слоя кэшавання кожны з іх адправляе свой сабець запыт:
Profile Screen → API Call
Settings Screen → API Call
Dashboard Screen → API Call
Рэзультат: тры разныя запыты сеті для тых сабеў дадзенняў.
З React Query
Profile Screen → API Call
Settings Screen → Cached Data
Dashboard Screen → Cached Data
Рэзультат гэты раз: толькі адны запыт сеті.
React Query храніць рэзультаты пад ключам запыту і дзеліць гэты кэшаваныя данні між усімі компонентамі, якія іх запрашваюць. Кожны экран, який пазней запрашвае той самы ключ, атрымлівае кэшавануюе значэнне мгновена, а фонова перзапытка можа тыхо падтрымліваць яго актуальнасць.
Рэзультат у працоўнай сіткі
На экранах, якія выкарыстоўваюцца часта, гэта дае:
- Знaczна меньшае колькасць дубліруючыхся запытов да API
- Меньшая навантажэнна на серверы бэкенду
- Швейцарскія пераходы між экранамі
Порэванаўленне #2: Карабкаванне эфектывасці
Можна сказаць, што самэ карабкаванне ў тым моменте, дзе React Query даўа найбольшую практычную корысть.
Калі той самы запит зноў выкананы пры тым, што карабкованая копія ўсё яшчэ не стала некорыстной:
useQuery({
queryKey: ["products"],
queryFn: getProducts,
staleTime: 300000,
});
Інтэрфейс можа адразу паказаць карабкованыя данні, пры чым React Query за жаданням тыхо апштучвае іх у фоне. Карабкованыя елементы застаюцца і ў канечнай часе адбіваецца ўпорядкуванне некорыстных дадзеных па настройкам, якія вы кантролюеце.
Рэальны прыклад
Разглядзім экран супылку продуктав у аплікацыі для е-камерцыі.
Без карабкавання адкрыць экран означае:
Open Products
↓
Network Request
↓
Navigate Back
↓
Open Products Again
↓
Network Request
З викорыстаннем React Query той самы процес стае такім:
Open Products
↓
Network Request
↓
Navigate Back
↓
Open Products Again
↓
Instant Cached Data
Разлік заключаецца у тым, што аплікацыя здаецца значна быстрэйшай для чалавека, які ёю корыстуецца.
Порэванаўленне #3: Статусы заваношчання
Перад вжываннем React Query для стежэння за статусам заваношчання патрэбна была робота з калькамі логічных значэнняў:
const [loading, setLoading] = useState(false);
const [refreshing, setRefreshing] = useState(false);
const [isRetrying, setIsRetrying] = useState(false);
Пасцялей, адзін вызов хука прадстаўляе ўсё, што трэба:
const {
isLoading,
isFetching,
isRefetching,
} = useQuery(...)
React Query разлічае першыя запускі дадзенняў і будучыя запросы на фоне, што значна спрощае розумеенне логікі інтэрфейса.
Рэальная выгода
У замест на показ спінера на всім экране пасля кожного запросу, прыкладны програма можа розразлічваць:
- Пачатковы запуск: спінер на всім экране
- Апдэйт на фоне: маленькі, непразойлівы спінер
- Дадзеныя ўжо зберагліся: жодных відчутных перарываў
Гэта дае значна лепшую адзывчаснасць для ўсіх, хто выкарыстоўвае прыкладную програму.
Порэванне #4: падтрымка без інтернету
Працэс працы без інтернету — адна з тых рэчаў, якія команды часта недаценяюць.
Работа з гэтым у ручны спосабе зазвычай выглядае так:
Check Connectivity
Pause Requests
Retry Later
Handle Errors
Refetch On Reconnect
Это значыць, што логіка з’яўлення з’язку розмешчаецца ў разных частках кодавой базы.
React Query заместа таго прысвячае вбудованая адміністрацыя ў режымах онлайн і офлайн, а таксама можлівасць павтовыяго запрашэння дадзеных, якае реагуе на падключэння да сеті. У React Native можна выкарыстоўваць onlineManager разам з прыемнікамі статусу сеті платформы, ўскладнюючы такія процесы.
Напрыклад:
onlineManager.setEventListener(...)
React Query таксама можна налаштаваць на роботу ў режыме «офлайн-перш», прадзействуючы ў згоднасці з гэтым яго поведзенне ў сеті.
Рэальны прыклад
Возьмімо як прыклад аплікацыю для чытання новасцей.
За весь дзень статус падключэння корыстувальца можа выглядаць так:
- Ранак: онлайн
- Пасля обеду: офлайн
- Вечар: знова онлайн
Пратаму, нават калі корыстувальнік у офлайн-режыме, ранейшыя запісаны статті застаюцца доступнымі для чытання, а калі падключэнне восстанавліваецца, новы контент можа автаматычна синхронізавацца.
Практычныя прыклады выкарыстоўвання
1. Аплікацыі новасцей
Што гэта дае:
- Артыкулы, якія зберагаюцца ў кэшы
- Автаматычна аднавленне фону
- Зменшэнне загальнага трафіку API
- Магчымас чытання далей без падключэння да інтернету
2. Аплікацыі для е-камеры
Што гэта дае:
- Спісы продуктав, якія зберагаюцца ў кэшы
- Заздалегіджана загрузка катэгарыяў
- Шырэйя навігацыя между роздзеламі
- Значна болей павольны процес апрання
React Query таксама падтрымлівае заздалегіджана загрузку дадзэнняў прычым пераводзе на навігацыю, чым зменшуе вялікі час чакання.
3. Аплікацыі для панелей керування
Што гэта дае:
- Віджэты, якія самі аднавляюцца
- Кэш, які дзейнае на адночасна ў калька экранаў
- Зменшэнне сетавага трафіку
- Значна простэйшая система керування станам
Гэты падход особліва добра падходзіць для панелей аналітыкі і панелей керування.
Што мы насправдзе адключылі
Калі міграцыя была завершана:
Удалена
- Самастраўлены механізм карэткавання стану заваношчання
- Ручны код для павторных спроб
- Дуплікаты запытанняў API
- Шаблон для апдэйта дадзеных праз прасунуць экран
- Самастраўленая логіка кэшавання
- Ручныя механізмы павторнага запытвання
Дадата
- Сама бібліятэка React Query
- Ключы запытанняў
- Экземпляр
QueryClient
Рэзультат: прыбліжна 500 ліній коду для карэткавання дадзеных через API больш не было патрэбны.
Калі React Query можа не быць неабходным
Іспытваць React Query можа быць занадта — якщо:
- Ваша аплікацыя выкананае толькі калькі запытанняў API
- Дадзеныя практычна не змінююцца
- Кэшавання сапраўды не патрэбна
- Працаванне без інтарнету не мае значэння для вашага выкарыстоўвання
Адзначыцца, што для большасці прыкладнаў у працэвыканні выгоды з викорыстанняя React Query зазвычай досыць быстра пераважаюць пачатковую складнасць навучэння.
Заключныя меркі
React Query — гэта не проста ўзрачынны спосаб для запрашэння дадзеных.
Ён выступае як цэлая система карыстоўвання станам сервера, якая абмежвае павтаральны код API і водночас палягчае кэшаванне, прыемнасць завантажэння, эфектыўнасць сеті і роботу без падключэння да інтарнету.
Найбольшыя выгоды тут крыліся не столькі у чыстай працэздатнасці.
Гэта была скарблівае падцягванне сложнасці.
Менш коду. Менш багоў. Кращыя умовы для ўжывання прыкладнага праграмы.
Самэ гэта соўтаванне зробіла міграцыю значным крокам.