iconASIKIN

Optimistic Update di ReactJs: Cara Membuat UI Lebih Cepat dan Responsif

by El - 25 November 2025https://kqiyzwsbtyulwzyudyvj.supabase.co/storage/v1/object/public/banners/banners/jsh821ysb-optimistic-react.webp

Dalam aplikasi web modern, kecepatan dan responsivitas UI sangat menentukan pengalaman pengguna. Salah satu teknik paling efektif untuk meningkatkan performa UI adalah Optimistic Update. Teknik ini memungkinkan perubahan tampilan terjadi sebelum server merespons, sehingga aplikasi terasa jauh lebih cepat dan interaktif.

Artikel ini akan membahas konsep Optimistic Update, manfaatnya, serta cara mengimplementasikannya di React.js—baik dengan state biasa, React Query.

Apa Itu Optimistic Update?

Optimistic Update adalah pendekatan untuk memperbarui UI secara langsung seolah-olah operasi sudah berhasil, tanpa menunggu respons server.

Dengan kata lain:

“Kita berasumsi operasi akan sukses—UI langsung di-update, lalu jika server gagal, barulah kita rollback.”

Teknik ini sangat berguna pada aplikasi dengan interaksi tinggi seperti

  • E-commerce (add to cart, wishlist)
  • Sosial media (like, comment)
  • Dashboard manajemen data (CRUD)
  • Chat dan real-time notifications

Mengapa Optimistic Update Penting?

  • ✔ 1. Mengurangi Latency Pengguna tidak perlu menunggu respon API → UI langsung berubah.
  • ✔ 2. Meningkatkan Kesan Responsif Aplikasi terasa lebih cepat dan smooth.
  • ✔ 3. Mengurangi Beban pada Server Interaksi kecil tidak perlu menunggu round-trip penuh.
  • ✔ 4. Meningkatkan UX Secara Signifikan Pengguna merasa aksi mereka langsung berdampak.

Contoh Kasus: Like Button dengan Optimistic Update di ReactJS

Misalkan kita punya sebuah postingan, dan user bisa menekan tombol Like. Dengan Optimistic Update, angka like akan langsung bertambah/dikurangi tanpa menunggu server, sehingga terasa cepat dan responsif.

Contoh useState

Di sini kita update UI langsung, lalu rollback jika request gagal.

Kelebihan memiliki UI yang terasa cepat dan tidak ribet, Tetapi ini juga memiliki kekurangan karena perlu rollback manual dan tidak cocok untuk skala besar.

import React, { useState } from "react";

function LikeButton() {
  const [liked, setLiked] = useState(false);
  const [likes, setLikes] = useState(10);

  const handleLike = async () => {
    const oldLiked = liked;
    const oldLikes = likes;

    // 1. Optimistic update
    setLiked(!liked);
    setLikes(liked ? likes - 1 : likes + 1);

    try {
      // 2. Kirim request ke server
      const res = await fetch("/api/like", {
        method: "POST",
        body: JSON.stringify({ like: !liked }),
      });

      if (!res.ok) throw new Error("Gagal update like!");

      // Jika sukses → biarkan UI seperti itu
    } catch (err) {
      console.error(err);

      // 3. Rollback jika gagal
      setLiked(oldLiked);
      setLikes(oldLikes);
      alert("Terjadi masalah, tidak bisa update like.");
    }
  };

  return (
    <button onClick={handleLike}>
      {liked ? "❤️" : "🤍"} {likes} Likes
    </button>
  );
}

export default LikeButton;

Contoh dengan React Query (TanStack)

React Query menyediakan lifecycle onMutate, onError, dan onSettled untuk menangani optimistic update otomatis.

Memiliki banyak kelebihan seperti rollback otomatis, data konsisten, cocok untuk skala besar, dan mengurangi boilerplate.

import { useMutation, useQueryClient } from "@tanstack/react-query";

function LikeButton({ postId, initialLiked, initialLikes }) {
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: (newValue) =>
      fetch(`/api/posts/${postId}/like`, {
        method: "POST",
        body: JSON.stringify({ like: newValue }),
      }).then((res) => {
        if (!res.ok) throw new Error("Server error");
        return res.json();
      }),

    // Optimistic update
    onMutate: async (newLikeStatus) => {
      await queryClient.cancelQueries(["post", postId]);

      const previousData = queryClient.getQueryData(["post", postId]);

      // 1. Update UI langsung
      queryClient.setQueryData(["post", postId], (old) => ({
        ...old,
        liked: newLikeStatus,
        likes: old.likes + (newLikeStatus ? 1 : -1),
      }));

      // return data untuk rollback
      return { previousData };
    },

    // Rollback kalau gagal
    onError: (err, newLikeStatus, context) => {
      queryClient.setQueryData(["post", postId], context.previousData);
    },

    // Revalidate data (biar pasti benar)
    onSettled: () => {
      queryClient.invalidateQueries(["post", postId]);
    },
  });

  const post = queryClient.getQueryData(["post", postId]) || {
    liked: initialLiked,
    likes: initialLikes,
  };

  const toggleLike = () => {
    mutation.mutate(!post.liked);
  };

  return (
    <button onClick={toggleLike}>
      {post.liked ? "❤️" : "🤍"} {post.likes} Likes
    </button>
  );
}

Simulasi Backend (Opsional Untuk Testing)

Kalau kamu mau coba, bisa pakai server palsu seperti:

app.post("/api/like", (req, res) => {
  // Simulasi delay server 1 detik
  setTimeout(() => {
    // Simulasi gagal 20% untuk melihat rollback
    if (Math.random() < 0.2) {
      return res.status(500).json({ error: "Server error" });
    }
    res.json({ success: true });
  }, 1000);
});

Kesimpulan

  • Optimistic Update membuat Like Button terasa sangat cepat.
  • UI berubah dulu → server menyusul.
  • Jika error → data dikembalikan seperti semula.
  • Bisa diterapkan dengan useState atau library seperti React Query dari tanstack.