Зміст
Коротко
На Dev.to розібрали робочий рецепт офлайн-записів у React: TanStack Query як реактивний кеш, Dexie поверх IndexedDB і невелика черга вихідних. Мета — щоб додавання товару в «п’ятому ряду» пережило закриття застосунку і доїхало до сервера вже в автобусі. Три опори: зберегти кеш і призупинені мутації, зареєструвати обробники за замовчуванням, щоб їх можна було зібрати знову після перезапуску, і видавати клієнтські ідентифікатори плюс ідемпотентний повтор.
Що сталося
Користувач помічає не архітектуру, а поведінку: запис не зник після збою, слабкої мережі і вбитого процесу. Автор пропонує вважати TanStack Query дзеркалом локальної бази, а не єдиним місцем правди. Спочатку зміну пишуть у Dexie, потім оновлюють кеш запитів, а на сервер операція йде, коли зв’язок є. Це ближче до блокнота в кишені, ніж до форми, що живе лише поки відкрита вкладка: аркуш переживе розряд батареї, а список покупок можна переписати в систему вже вдома.
Перший крок — збереження реактивного кешу в IndexedDB через PersistQueryClientProvider і асинхронний persister. На старті застосунок піднімає узгоджений локальний знімок і викликає resumePausedMutations. Важливо виставити gcTime не коротшим за строк життя persister і через shouldDehydrateMutation зберігати лише ті призупинені мутації, які ви вмієте відновити. Інакше після перезапуску спливуть «зомбі»: запис є, а функції для повтору немає.
Другий крок — queryClient.setMutationDefaults зі стабільними ключами на кшталт ['items', 'create']. У збереженій мутації лежать змінні і метадані, але не замикання з mutationFn. Обробники за замовчуванням потрібно зареєструвати до виклику відновлення, зазвичай імпортом модуля під час завантаження застосунку. Третій крок — клієнтський ідентифікатор у onMutate, негайний запис у таблиці Dexie і запис у чергу вихідних із дією, ключем мутації, змінними і часом. Коли з’являється мережа, чергу дренують по порядку, на сервер іде заголовок на кшталт Idempotency-Key, успішні елементи з черги видаляють.
Чому це важливо
Звичайний оптимістичний інтерфейс без довговічного шару бреше користувачеві рівно до перезавантаження. Мережа «моргнула», вкладку закрили — і локальна правка зникла разом із пам’яттю процесу. Черга вихідних і ідентифікатор клієнта перетворюють повтор на безпечну операцію: сервер може отримати той самий запит двічі і не створити дублікат, якщо шанує ключ ідемпотентності.
Платформа теж диктує межі. Background Sync у Chrome допомагає, в iOS Safari — ні. Тому повтор при появі мережі, при поверненні вкладки і на старті застосунку потрібен як базовий контур, а не як опція. У кількох вкладках без вибору провідного процесу чергу оброблять двічі; BroadcastChannel або Web Locks тримають одного лідера. Експоненційний відкат із тремтінням закриває тимчасові збої, а постійні помилки перевірки (зазвичай відповіді 4xx) краще зняти з черги і показати людині, а не крутити нескінченно.
На практиці
Стаття дає зв’язку прийомів і начерки коду, не готовий пакет під ваш домен. Перед копіюванням вирішіть, що є джерелом правди для запису — локальна база чи кеш запитів.
- Пишіть у
Dexieпершим; хайTanStack Queryреагує на зміну локальних даних. - Зберігайте лише відновлювані призупинені мутації; без обробників за замовчуванням після перезапуску вони марні.
- Реєструйте
setMutationDefaultsдоresumePausedMutations. - Ставте клієнтський ідентифікатор і кладіть операцію в чергу вихідних у тому ж користувацькому жесті, що й оптимістичне оновлення.
- На сервері шануйте
Idempotency-Keyабо номери послідовності, щоб повтор не плодив дублікати. - Для пов’язаних сутностей відтворюйте чергу по порядку; дія
createмає прийти раніше заupdate. - За кількох вкладок оберіть одного лідера для спорожнення черги.
Підсумок
Стійкий офлайн у React тут складається з трьох обіцянок: стан і черга переживають смерть процесу в IndexedDB, призупинені мутації можна зібрати знову за обробниками за замовчуванням, повтор безпечний завдяки клієнтським ідентифікаторам і дедуплікації на сервері. Мережа лишається ненадійною — але користувач продовжує працювати, бачить статус синхронізації і чекає доставки, коли з’являється зв’язок.



Коментарі