Episode ini membahas Context API untuk shared state, useReducer untuk logika state yang kompleks, lalu Zustand dan Redux Toolkit sebagai state manager modern. Kalian juga belajar best practice global state versus local state agar arsitektur tetap sehat.

Props yang mengalir lima level ke bawah — yang disebut prop drilling — membuat kode sulit dirawat. Episode 10 memperkenalkan solusinya: cara berbagi state antar komponen tanpa menembus setiap lapisan.
Kita mulai dari Context API bawaan React dan useReducer untuk logika state yang kompleks, lalu melihat dua state manager modern yang banyak dipakai produksi: Zustand dan Redux Toolkit. Terakhir, aturan main global state versus local state yang menentukan arsitektur proyek kalian.
Context menyediakan nilai ke seluruh subtree tanpa props berantai. Tiga langkah: buat context, sediakan nilai, lalu konsumsi:
import { createContext, useContext, useState } from "react"
const TemaContext = createContext("terang")
function Tombol() {
const tema = useContext(TemaContext)
return <button className={`tombol-${tema}`}>Klik</button>
}
function App() {
const [tema, setTema] = useState("terang")
return (
<TemaContext.Provider value={tema}>
<Tombol />
<button onClick={() => setTema(tema === "terang" ? "gelap" : "terang")}>
Ganti Tema
</button>
</TemaContext.Provider>
)
}const tema = useContext(TemaContext) membaca nilai context di komponen mana pun di dalam <TemaContext.Provider>. Semua komponen yang mengonsumsi context akan re-render saat nilai provider berubah.
Context paling cocok untuk nilai yang jarang berubah dan dibaca banyak tempat: tema, bahasa, atau identitas pengguna. Untuk state yang berubah cepat dan kompleks, context saja kurang nyaman — di sanalah state manager masuk.
useReducer mengelola state yang perubahannya kompleks. Semua update dinyatakan sebagai action yang diproses satu fungsi:
import { useReducer } from "react"
function reducer(state, action) {
switch (action.type) {
case "tambah":
return { ...state, total: state.total + action.nilai }
case "reset":
return { total: 0 }
default:
return state
}
}
function Keranjang() {
const [state, dispatch] = useReducer(reducer, { total: 0 })
return (
<div>
<p>Total: {state.total}</p>
<button onClick={() => dispatch({ type: "tambah", nilai: 5 })}>+5</button>
<button onClick={() => dispatch({ type: "reset" })}>Reset</button>
</div>
)
}dispatch({ type: "tambah", nilai: 5 }) mengirim action ke fungsi reducer, yang mengembalikan state baru. Logika update tersentralisasi dan mudah diuji, tidak tersebar di banyak handler.
Zustand populer karena API-nya kecil dan tidak butuh provider di level atas:
npm install zustandimport { create } from "zustand"
const useKeranjang = create((set) => ({
total: 0,
tambah: (nilai) => set((state) => ({ total: state.total + nilai })),
reset: () => set({ total: 0 }),
}))
function TombolTambah() {
const tambah = useKeranjang((state) => state.tambah)
return <button onClick={() => tambah(5)}>+5</button>
}create((set) => ({ ... })) membangun store dengan state dan action sekaligus. Komponen cukup memanggil useKeranjang((state) => state.tambah) untuk memakai action — tanpa Provider, tanpa reducer terpisah.
Redux Toolkit adalah versi modern Redux dengan createSlice yang menyatukan state, reducer, dan action:
npm install @reduxjs/toolkit react-reduximport { createSlice, configureStore } from "@reduxjs/toolkit"
const keranjangSlice = createSlice({
name: "keranjang",
initialState: { total: 0 },
reducers: {
tambah(state, action) { state.total += action.payload },
reset(state) { state.total = 0 },
},
})
const store = configureStore({ reducer: keranjangSlice.reducer })createSlice membuat reducer dan action creator sekaligus. Redux Toolkit cocok untuk tim besar dengan banyak developer karena strukturnya eksplisit dan memakai Redux DevTools untuk debugging.
Recoil menawarkan atom dan selector yang terpusat pada data. Pilihan antar library sebenarnya bergantung kebutuhan: Zustand untuk ringkas, Redux Toolkit untuk skala tim, Recoil untuk pola atom.
Jangan menaruh semua state secara global. Aturan sederhana:
Mulailah dengan useState, naik ke Context atau useReducer saat prop drilling mulai mengganggu, dan baru gunakan state manager global saat benar-benar dibutuhkan. Banyak aplikasi tidak pernah butuh Redux — jangan pasang karena tren.
npm install zustand
npm run devPraktikkan: pindahkan state tema dari contoh Context di atas ke store Zustand, lalu bandingkan struktur kodenya. Keduanya valid — pilih yang paling nyaman untuk kasus kalian.
Episode 10 menyelesaikan dilema state management: Context API untuk shared state sederhana, useReducer untuk logika kompleks, Zustand dan Redux Toolkit sebagai state manager modern, plus aturan global versus local state.
Inti yang harus dibawa pulang:
useReducer menyalurkan semua update melalui action dan satu reducer.Di episode 11 selanjutnya kita akan membahas forms & validation — controlled dan uncontrolled components, React Hook Form dengan validation rules, schema validation memakai Yup atau Zod, serta accessibility form dan input feedback. Form adalah pintu masuk data dari pengguna.