← all posts

Mengelola State di React dengan Efektif

7/3/2026

Mengelola State di React dengan Efektif

Mengelola State di React dengan Efektif

Manajemen state adalah salah satu topik paling kompleks dalam pengembangan React. Setiap aplikasi memiliki kebutuhan yang berbeda, dan tidak ada solusi tunggal yang cocok untuk semua.

Hierarki Manajemen State

+-------------------------------------------------------------+
|   TINGKAT KEBUTUHAN                                         |
|                                                             |
|   +---------------------------------------------------+    |
|   | 5. Global State (Zustand/Redux)                    |    |
|   | Data: Auth, Cart, Notifikasi                       |    |
|   +---------------------------------------------------+    |
|                                                             |
|   +---------------------------------------------------+    |
|   | 4. Server State (TanStack Query/SWR)              |    |
|   | Data: API responses, Caching, Auto-refetch        |    |
|   +---------------------------------------------------+    |
|                                                             |
|   +---------------------------------------------------+    |
|   | 3. Context API                                    |    |
|   | Data: Theme, Locale, User Preferences             |    |
|   +---------------------------------------------------+    |
|                                                             |
|   +---------------------------------------------------+    |
|   | 2. Lifting State Up                               |    |
|   | Data: Shared antar sibling components             |    |
|   +---------------------------------------------------+    |
|                                                             |
|   +---------------------------------------------------+    |
|   | 1. Local State (useState)                         |    |
|   | Data: Form input, Toggle UI, Tab aktif            |    |
|   +---------------------------------------------------+    |
|                                                             |
|   MULAI DARI SINI — gunakan yang paling sederhana dulu!   |
+-------------------------------------------------------------+

1. Local State dengan useState

Gunakan untuk data yang hanya dibutuhkan satu komponen:

import { useState } from "react";

export default function ContactForm() {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [submitted, setSubmitted] = useState(false);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    await fetch("/api/contact", {
      method: "POST",
      body: JSON.stringify({ name, email }),
    });
    setSubmitted(true);
  };

  // ...render form
}

2. Lifting State Up

Ketika dua komponen sibling butuh data yang sama, pindahkan state ke parent:

// Parent: menyimpan state, menurunkan ke child
function Dashboard() {
  const [search, setSearch] = useState("");

  return (
    <>
      <SearchBar value={search} onChange={setSearch} />
      <ProjectList filter={search} />
    </>
  );
}

3. Context API

Hindari props drilling dengan Context:

// app/contexts/ThemeContext.tsx
"use client";
import { createContext, useContext, useState } from "react";

type Theme = "dark" | "light";

const ThemeContext = createContext<{
  theme: Theme;
  toggle: () => void;
} | null>(null);

export function ThemeProvider({ children }: { children: React.ReactNode }) {
  const [theme, setTheme] = useState<Theme>("dark");

  return (
    <ThemeContext.Provider value={{ theme, toggle: () => setTheme(t => t === "dark" ? "light" : "dark") }}>
      {children}
    </ThemeContext.Provider>
  );
}

4. Server State — Yang Paling Sering Disalahgunakan

JANGAN simpan data API di global state! Gunakan library khusus:

// ❌ SALAH: Simpan data API di Redux
dispatch(setPosts(data)); // Manual caching, manual loading state

// ✅ BENAR: Gunakan TanStack Query
import { useQuery } from "@tanstack/react-query";

function BlogList() {
  const { data, isLoading, error } = useQuery({
    queryKey: ["posts"],
    queryFn: () => fetch("/api/posts").then(r => r.json()),
  });

  // Dapat caching, auto-refetch, loading/error state GRATIS!
}

5. Global State (Zustand/Redux)

Hanya untuk data yang benar-benar global. Zustand adalah pilihan ringan:

// store/auth-store.ts
import { create } from "zustand";

interface AuthStore {
  user: { name: string; email: string } | null;
  login: (user: { name: string; email: string }) => void;
  logout: () => void;
}

export const useAuthStore = create<AuthStore>((set) => ({
  user: null,
  login: (user) => set({ user }),
  logout: () => set({ user: null }),
}));

Tabel Keputusan

SituasiSolusiAlasan
Form input, toggle, tabuseStateHanya lokal, sederhana
Dua komponen sibling share dataLifting state upTidak perlu eksternal
Tema, locale, user preferencesContext APIJarang berubah
Data dari APITanStack QueryCaching, refetch, dll gratis
Auth, cart, notifikasi globalZustandRingan, simpel
Aplikasi kompleks dengan banyak stateRedux ToolkitDevTools, middleware

Kesimpulan: Mulailah dari yang paling sederhana (useState). Tambahkan kompleksitas hanya ketika benar-benar dibutuhkan. Jangan over-engineering!