Asosiy kontentga o‘tish
Innovialabs

React’da optimistik interfeys yangilanishlari: patternlar va qaytarish

Chuqur4 daq

Qisqacha

Optimistik UI kutilgan natijani darhol ko‘rsatadi va server bilan fonda sinxronlanadi; unga qaytarish uchun snapshot, poyga va dublikatlardan himoya kerak, soxta «muvaffaqiyat» pulga tushadigan joyda esa ishlatilmaydi.

Optimistik UI nima va qachon o‘zini oqlaydi

Optimistik yangilanish — interfeysni so‘rov allaqachon muvaffaqiyatli o‘tgandek o‘zgartirish, server javob bergach esa uni tasdiqlash yoki qaytarish. Layk bir zumda qizaradi, vazifa ro‘yxatda spinnersiz paydo bo‘ladi, nomi o‘zgartirilgan fayl yangi nomini darhol ko‘rsatadi.

Yondashuv uchta shart bajarilganda yaxshi ishlaydi:

  • operatsiya deyarli har doim muvaffaqiyatli (validatsiya klientda o‘tgan);
  • natijani kirish ma’lumotlaridan oson taxmin qilish mumkin;
  • xatoni vizual arzon qaytarish mumkin va u foydalanuvchini muhim narsa haqida chalg‘itmaydi.

Agar bittasi bajarilmasa — halol kutish holatini ko‘rsating.

useOptimistic: React’ning o‘rnatilgan yondashuvi

React 19 da useOptimistic hooki bor. U faqat action yoki transition bajarilayotgan paytda mavjud bo‘ladigan vaqtinchalik holatni qaytaradi; tugagach React siz uzatgan haqiqiy holatga qaytadi.

import { useOptimistic } from "react";

function TodoList({ todos, addTodo }) {
  const [optimisticTodos, addOptimistic] = useOptimistic(
    todos,
    (current, draft) => [...current, { ...draft, pending: true }]
  );

  async function formAction(formData) {
    const draft = { id: crypto.randomUUID(), text: formData.get("text") };
    addOptimistic(draft);
    try {
      await addTodo(draft); // muvaffaqiyatda ota komponentdagi `todos`ni yangilashi shart
    } catch {
      showToast("Vazifani saqlab bo‘lmadi");
    }
  }

  return (
    <form action={formAction}>
      <input name="text" required />
      <ul>
        {optimisticTodos.map((t) => (
          <li key={t.id} style={{ opacity: t.pending ? 0.5 : 1 }}>{t.text}</li>
        ))}
      </ul>
    </form>
  );
}

Asosiysi:

  • Qaytarish avtomatik: action xato bersa, transition tugashi bilan optimistik element yo‘qoladi — axir haqiqiy todos o‘zgarmagan.
  • Teskari tomoni: muvaffaqiyatda haqiqiy holat ham yangilanishi kerak (revalidatsiya, ota komponentda setState, revalidatePath bilan Server Action). Aks holda element action tugagach yo‘qoladi.
  • addOptimistic oddiy hodisa ishlovchisida emas, action yoki startTransition ichida chaqiriladi.

TanStack Query: snapshot, yangilash, qaytarish

Ma’lumotlar TanStack Query keshida saqlansa, klassik pattern onMutate ustiga quriladi:

const queryClient = useQueryClient();

const addTodo = useMutation({
  mutationFn: (todo: Todo) => api.addTodo(todo),
  onMutate: async (todo) => {
    await queryClient.cancelQueries({ queryKey: ["todos"] });
    const previous = queryClient.getQueryData<Todo[]>(["todos"]);
    queryClient.setQueryData<Todo[]>(["todos"], (old = []) => [...old, todo]);
    return { previous };
  },
  onError: (_err, _todo, ctx) => {
    queryClient.setQueryData(["todos"], ctx?.previous);
  },
  onSettled: () => queryClient.invalidateQueries({ queryKey: ["todos"] }),
});

Qadamlar:

  1. Eski refetch optimistik ma’lumotlarni ustidan yozmasligi uchun joriy so‘rovlarni bekor qiling.
  2. Keshning snapshotini saqlang.
  3. Keshga kutilgan natijani yozing.
  4. Xatoda snapshotni qaytaring va foydalanuvchiga xabar bering.
  5. Har qanday holatda haqiqat manbasini olish uchun ma’lumotlarni qayta so‘rang.

Soddaroq variant: keshga tegmasdan, isPending true bo‘lgan paytda mutation.variablesni yarim shaffof element sifatida chizing. Qaytaradigan narsa yo‘q — xatoda element shunchaki yo‘qoladi.

Poyga holatlari va dublikatlar

Optimistik UI parallellik muammolarini ko‘zga ko‘proq tashlaydi. Tipik holatlar:

MuammoNima bo‘ladiQanday hal qilinadi
Eskirgan refetchMutatsiyadan oldin boshlangan so‘rov eski ma’lumot qaytaradiYangilashdan oldin cancelQueries
Parallel mutatsiyalarBirining qaytarilishi boshqasini o‘chiradigan snapshotni tiklaydiButun snapshotni emas, faqat o‘z o‘zgarishingizni bekor qiling (id bo‘yicha filtr)
Tartibsiz javoblarBirinchi bosishga javob ikkinchisidan keyin keladiDeltani emas, yakuniy holatni («liked: true») yuboring; versiyalarni solishtiring
Erta invalidatsiyaBirinchi mutatsiyadan keyingi refetch boshqalarning optimistik ma’lumotini o‘chiradiKalit bo‘yicha isMutating birgacha tushganda invalidatsiya qiling
Ikki marta yuborishFoydalanuvchi yana bosadi, chunki «allaqachon ishladi»Klientda yaratilgan id yoki idempotency key, serverda deduplikatsiya

Klientda yaratilgan ID ikki muammoni birdaniga hal qiladi: vaqtinchalik id’ni haqiqiysiga almashtirish kerak emas, bir xil id bilan takroriy so‘rovni esa backendda oson saralab tashlash mumkin.

Optimistik UI qayerda xavfli

Xato haqiqiy oqibatlarga olib keladigan joyda muvaffaqiyatni ko‘rsatmang:

  • to‘lovlar, o‘tkazmalar, balansni to‘ldirish — foydalanuvchi pul ketdi deb o‘ylab, vkladkani yopib qo‘yishi mumkin;
  • qoldig‘i cheklangan buyurtmalar va bronlar, bu yerda mavjudlikni server hal qiladi;
  • qaytarib bo‘lmaydigan harakatlar: xat yuborish, nashr qilish, butunlay o‘chirish;
  • natijasini oldindan aytib bo‘lmaydigan murakkab server validatsiyali operatsiyalar.

Bunday joylarda aniq kutish holati kerak: bloklangan tugma, progress indikatori va faqat server javobidan keyin tasdiqlash ekrani.

Ko‘p uchraydigan xatolar

  • Xato haqida xabar yo‘q: element jimgina yo‘qoladi va foydalanuvchi sababini tushunmaydi.
  • Parallel mutatsiyalarda butun keshni qaytarib, boshqalarning o‘zgarishlarini yo‘qotish.
  • Yakuniy refetch unutilgan — klient va server bir-biridan uzoqlashadi.
  • Muhim ma’lumotlarni «Bekor qilish» tugmasisiz optimistik o‘chirish.

Ko‘p beriladigan savollar

Ma’lumotlar Server Components yoki lokal holat orqali kelsa va actionlar orqali o‘zgarsa — useOptimistic. Agar server ma’lumotlari allaqachon TanStack Query keshida saqlansa, barcha komponentlar bir xil holatni ko‘rishi uchun shu keshni onMutateda yangilang.

Bunda yordam beramiz

O‘zingiz shug‘ullanmasdan natija olishni istasangiz — biz har kuni shu bilan shug‘ullanamiz.

Loyihani muhokama qilish

Yana o‘qing

G‘oya yoki vazifangiz bormi? Bizga aytib bering

Ish kuni davomida javob beramiz va yechim taklif qilamiz. Konsultatsiya bepul.