Mengapa React Context tidak selalu cukup

Mengapa React Context tidak selalu cukup

1. Context itu bukan "state management"

React Context hanya menyediakan cara untuk membagikan data ke komponen anak tanpa harus prop drilling. Tapi dia tidak mengelola state dengan efisien, hanya mendistribusikannya.

Misalnya:

const ThemeContext = createContext();

function App() {
  const [theme, setTheme] = useState("light");

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Child />
    </ThemeContext.Provider>
  );
}

Masalah: Setiap kali theme berubah, semua komponen yang pakai useContext(ThemeContext) akan re-render, meskipun mereka cuma butuh sebagian kecil dari state.


2. Context re-render problem

Ketika value di <Provider> berubah, semua consumer re-render. Jika ada 50 komponen yang pakai context itu, semua akan render ulang — walau yang berubah cuma 1 field kecil.

Ini berdampak pada performance bottleneck.


3. Tidak efisien untuk state kompleks

Kalau kamu punya state global yang:

  • besar dan nested,

  • sering berubah,

  • digunakan oleh banyak komponen di berbagai tempat,

... maka context akan menjadi berat dan sulit dikontrol.


Apa itu Zustand?

Zustand adalah state management library untuk React (dan kadang juga digunakan di Next.js). Ia dibuat oleh tim yang sama dengan Jotai dan Valtio (Poimandres team).

Zustand menyediakan cara ringan, cepat, dan scalable untuk mengelola global state tanpa boilerplate berlebihan seperti Redux, dan tanpa overhead Context API.

Apa yang diselesaikan oleh Zustand

1. Fine-grained re-render

Zustand melakukan selective subscription: Komponen hanya akan re-render jika bagian state yang mereka pakai berubah.

import { create } from "zustand";

const useStore = create((set) => ({
  count: 0,
  inc: () => set((state) => ({ count: state.count + 1 })),
}));

function Counter() {
  const count = useStore((state) => state.count); // hanya re-render kalau count berubah
  return <h1>{count}</h1>;
}

Ini jauh lebih efisien dibanding Context karena re-render-nya granular dan terkontrol.


2. Simplicity dan minimal boilerplate

Redux, MobX, atau Context + Reducer biasanya verbose.

Zustand:

  • tidak butuh reducer, action, dispatcher

  • tidak perlu provider di root

  • bisa diakses dari mana pun (termasuk di luar React component!)


3. Bisa digunakan di luar React

Kamu bisa panggil store di tempat lain — misalnya di utility function atau service layer — karena Zustand store adalah plain JavaScript.

import { useStore } from "./store";

// bahkan di luar React component:
useStore.getState().inc();

4. Persist, Middleware, DevTools

Zustand punya fitur bawaan seperti:

  • persist() → simpan state ke localStorage/sessionStorage

  • subscribeWithSelector() → listener spesifik per field

  • devtools() → integrasi dengan Redux DevTools untuk debugging

  • immer() → memudahkan immutability


Analogi sederhana

Situasi
Solusi Ideal

Hanya perlu berbagi data global kecil (tema, bahasa)

Context sudah cukup

State global besar dan sering berubah

Zustand lebih efisien

Butuh akses state di luar React component

Zustand unggul

Mau setup ringan tanpa Redux

Zustand pilihan tepat


Kesimpulan

Aspek
React Context
Zustand

Tujuan

Distribusi data

Global state management

Re-render

Semua consumer

Hanya yang subscribe ke bagian tertentu

Boilerplate

Sedikit

Minimal

Performa

Kurang efisien untuk state dinamis

Sangat efisien

Akses di luar React

Tidak bisa

Bisa

Middleware/DevTools

Tidak ada

Ada


Kalau mau disingkat:

Zustand = Context tanpa re-render massal + Redux tanpa boilerplate.


Last updated