M
MLOG
2025. augusztus 19.Magyar

Fedezze fel a React useOptimistic hook-ot, amellyel gyorsabb, reszponzívabb felületeket hozhat létre optimista UI frissítésekkel. Tanulja meg használatát gyakorlati példákon keresztül.

React useOptimistic: Reszponzív Felhasználói Felületek Építése Optimista Frissítésekkel

A mai webfejlesztési környezetben a felhasználói élmény a legfontosabb. A felhasználók elvárják, hogy az alkalmazások reszponzívak legyenek és azonnali visszajelzést adjanak. Az érzékelt teljesítmény jelentős javításának egyik technikája az optimista UI frissítések alkalmazása. A React 18 bevezette a useOptimistic hookot, amely egy hatékony eszköz ennek a technikának a megvalósítására. Ez a cikk elmélyül az optimista UI koncepciójában, részletesen bemutatja a useOptimistic hookot, és gyakorlati példákat nyújt, hogy segítsen kihasználni azt a React alkalmazásaiban.

Mik azok az optimista UI frissítések?

Az optimista UI frissítések során a felhasználói felület frissítése megtörténik mielőtt a szerver megerősítené, hogy egy művelet sikeresen befejeződött. Ahelyett, hogy a szerver válaszára várnánk, a UI azonnal frissül, mintha a művelet sikeres lett volna. Ez az azonnali reakció illúzióját kelti, amitől az alkalmazás sokkal gyorsabbnak és gördülékenyebbnek érződik.

Vegyünk egy olyan esetet, amikor egy felhasználó rákattint egy "Like" gombra egy közösségi média bejegyzésen. Egy hagyományos megvalósításban az alkalmazás kérést küld a szervernek a kedvelés regisztrálásához, és megvárja a szerver megerősítő válaszát. Ezalatt a felhasználó enyhe késleltetést vagy egy betöltést jelző vizuális elemet tapasztalhat. Optimista frissítésekkel a "Like" gomb azonnal frissül, jelezve, hogy a felhasználó kedvelte a bejegyzést, anélkül, hogy a szerverre várna. Ha a szerver kérés később meghiúsul (pl. hálózati hiba miatt), a UI visszaállítható az előző állapotába.

Az optimista UI frissítések előnyei

  • Jobb Ă©rzĂ©kelt teljesĂ­tmĂ©ny: Az azonnali visszajelzĂ©s rĂ©vĂ©n az optimista frissĂ­tĂ©sek gyorsabbá Ă©s reszponzĂ­vabbá teszik az alkalmazást. Ez javĂ­tja az általános felhasználĂłi Ă©lmĂ©nyt, fĂĽggetlenĂĽl a tĂ©nyleges hálĂłzati kĂ©sleltetĂ©stĹ‘l.
  • Fokozott felhasználĂłi elkötelezĹ‘dĂ©s: Az azonnali vizuális megerĹ‘sĂ­tĂ©s arra ösztönzi a felhasználĂłkat, hogy többet interakciĂłba lĂ©pjenek az alkalmazással. Az Ă©rzĂ©kelt kĂ©sleltetĂ©sek csökkentĂ©se vonzĂłbb Ă©s Ă©lvezetesebb Ă©lmĂ©nyhez vezet.
  • Csökkentett felhasználĂłi frusztráciĂł: A szerver válaszaira valĂł várakozás frusztrálĂł lehet a felhasználĂłk számára, kĂĽlönösen lassĂş vagy megbĂ­zhatatlan hálĂłzati kapcsolatok esetĂ©n. Az optimista frissĂ­tĂ©sek minimalizálják az Ă©rzĂ©kelt várakozási idĹ‘t Ă©s csökkentik a felhasználĂłi frusztráciĂłt.

A React useOptimistic Hook bemutatása

A useOptimistic hook leegyszerűsíti az optimista UI frissítések megvalósítását React alkalmazásokban. Lehetőséget biztosít egy lokális állapot kezelésére, amely optimistán frissül a szerver válasza előtt, és visszaállítható, ha a szerver kérés meghiúsul.

Hook szignatĂşra:

            const [optimisticState, addOptimistic] = useOptimistic(initialState, updateFn);
            
  • initialState: Az állapot kezdeti Ă©rtĂ©ke. Ez az az Ă©rtĂ©k, amivel az állapot rendelkezik, mielĹ‘tt bármilyen optimista frissĂ­tĂ©s alkalmazásra kerĂĽlne.
  • updateFn: (Opcionális) Egy funkciĂł, amely megkapja az aktuális állapotot Ă©s az addOptimistic-nek átadott Ă©rtĂ©ket, Ă©s visszaadja az Ăşj optimista állapotot. Ha nincs funkciĂł megadva, az `addOptimistic`-nek átadott Ă©rtĂ©k felĂĽlĂ­rja az állapot aktuális Ă©rtĂ©kĂ©t.
  • optimisticState: Az optimista állapot aktuális Ă©rtĂ©ke. Ezt az állapotot kell használni a UI renderelĂ©sĂ©hez.
  • addOptimistic: Egy funkciĂł, amely elfogad egy Ă©rtĂ©ket Ă©s elindĂ­t egy optimista frissĂ­tĂ©st, felhasználva az `updateFn`-t, ha az meg van adva.

A useOptimistic gyakorlati példái

1. példa: Bejegyzés kedvelése (Közösségi média)

Térjünk vissza a közösségi média "Like" gomb példájához. A useOptimistic segítségével azonnal frissítjük a kedvelések számát, amikor a felhasználó a gombra kattint.

            
import React, { useState, useOptimistic } from 'react';

function LikeButton({ postId, initialLikes }) {
  const [isLiked, setIsLiked] = useState(false);
  const [optimisticLikes, addOptimistic] = useOptimistic(
    initialLikes,
    (state, newLike) => (newLike ? state + 1 : state - 1) //az updateFn növeli vagy csökkenti
  );

  const handleClick = async () => {
    const optimisticValue = !isLiked;
    setIsLiked(optimisticValue); // Lokális 'isLiked' állapot frissítése
    addOptimistic(optimisticValue); // optimisticLikes növelése vagy csökkentése

    try {
      // API hívás szimulálása a bejegyzés kedvelésére/visszavonására
      await new Promise((resolve) => setTimeout(resolve, 500)); // Hálózati késleltetés szimulálása

      // Itt frissítjük a szerver állapotát (pl. fetch vagy Axios használatával)
      // await api.likePost(postId, isLiked);
    } catch (error) {
      console.error('Hiba a bejegyzés kedvelésekor:', error);
      // A kérés sikertelensége esetén visszavonjuk az optimista frissítést
      setIsLiked(!optimisticValue);
      addOptimistic(!optimisticValue);
    }
  };

  return (
    
  );
}

export default LikeButton;

            

Magyarázat:

  1. Az optimisticLikes állapotot a kezdeti kedvelések számával inicializáljuk a useOptimistic(initialLikes) segítségével.
  2. Amikor a gombra kattintunk, meghívjuk az addOptimistic()-ot, hogy azonnal növeljük a kedvelések számát.
  3. Ezután szimulálunk egy API hívást a szerver frissítéséhez.
  4. Ha az API hívás meghiúsul, visszavonjuk az optimista frissítést az addOptimistic() ismételt meghívásával az ellenkező értékkel.

2. példa: Hozzászólás hozzáadása (Blogbejegyzés)

Nézzünk egy másik esetet: hozzászólás hozzáadása egy blogbejegyzéshez. Azt szeretnénk, hogy a hozzászólás azonnal megjelenjen anélkül, hogy megvárnánk a szerver megerősítését a létrehozásról.

            
import React, { useState, useOptimistic } from 'react';

function CommentForm({ postId }) {
  const [commentText, setCommentText] = useState('');
  const [optimisticComments, addOptimistic] = useOptimistic([]);

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!commentText.trim()) return;

    const newComment = {
      id: Date.now(), // Ideiglenes azonosító generálása
      text: commentText,
      author: 'Felhasználó',
      timestamp: new Date().toISOString(),
    };

    addOptimistic(prevComments => [...prevComments, newComment]);
    setCommentText('');

    try {
      // API hívás szimulálása a hozzászólás létrehozására
      await new Promise((resolve) => setTimeout(resolve, 500)); // Hálózati késleltetés szimulálása
      // Itt történne az API hívás, pl. api.addComment(postId, newComment);
      // Feltételezve, hogy az API hívás visszaadja a hozzászólást egy szerver által kiosztott azonosítóval, frissítenéd a hozzászólás azonosítóját

    } catch (error) {
      console.error('Hiba a hozzászólás hozzáadásakor:', error);
      // A kérés sikertelensége esetén visszavonjuk az optimista frissítést
      addOptimistic(prevComments => prevComments.filter(c => c.id !== newComment.id));
    }
  };

  return (