Галоўная / Артыкулы / Як React Query скасав 500 ліній у шары API даплы React Native

Як React Query скасав 500 ліній у шары API даплы React Native

Рэальны прыклад з выкарыстоўванням React Native, який паказвае, як пераход з ручнага запрашання дадзейнаў за дапамою useEffect на React Query парадукаў павтаральны код і паспячыў паўработці кэшу і лепшай роботы без падключення да Інтэрнету.

1364 слоў

Введэнне

Ёсць час тады, калі кодбаза 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 і водночас палягчае кэшаванне, прыемнасць завантажэння, эфектыўнасць сеті і роботу без падключэння да інтарнету.

    Найбольшыя выгоды тут крыліся не столькі у чыстай працэздатнасці.

    Гэта была скарблівае падцягванне сложнасці.

    Менш коду. Менш багоў. Кращыя умовы для ўжывання прыкладнага праграмы.

    Самэ гэта соўтаванне зробіла міграцыю значным крокам.