Episode ini merancang arsitektur Redux untuk tim besar: feature-based slices, RTK Query untuk seluruh server state, standar penulisan thunk dan mutation, code review patterns, kesadaran bundle size dengan tree-shaking, monitoring error, dan dokumentasi onboarding.

Semua teknik yang kalian pelajari — slices, thunks, RTK Query, testing, debugging — baru bermakna bila diorganisasi dalam arsitektur yang bisa dirawat banyak orang secara paralel. Episode 21 menjawab pertanyaan: seperti apa struktur Redux yang aman untuk tim besar dan siap produksi?
Kita menyusun konvensi tim: folder feature-based, RTK Query sebagai satu-satunya pintu server state, standar penulisan thunk dan mutation, serta pola code review. Lalu kita menutup dengan aspek kualitas deployment: kesadaran bundle size, tree-shaking, error monitoring, dan dokumentasi onboarding agar anggota baru cepat produktif.
Struktur folder dibangun per fitur, bukan per tipe file. Setiap fitur membawa slice, selectors, komponen, dan test-nya sendiri:
src/
app/ store.ts, hooks.ts, listenerMiddleware.ts
features/
auth/ authSlice.ts, authSelectors.ts, Login.tsx
posts/ postsSlice.ts, postsApi.ts, PostList.tsx
users/ usersSlice.ts, usersSelectors.ts
lib/ utilitas, baseQuery custom
test/ test store, MSW handlersAturan emasnya: satu fitur mandiri diubah, di-review, dan diuji tanpa menyentuh fitur lain. Perubahan pada features/auth seharusnya tidak memaksa siapa pun membuka features/posts. Kalian juga mengenali pola ini dari diskusi combineSlices di episode 11.
Konvensi: seluruh data yang berasal dari jaringan dikelola RTK Query; slice manual hanya menampung state UI dan client-only. Manfaatnya terlihat di episode 8-9 dan 17 — caching, invalidation, dan retry otomatis tidak perlu ditulis ulang per fitur:
export const usersApi = createApi({
reducerPath: "usersApi",
baseQuery: baseQueryWithAuth,
endpoints: (builder) => ({
listUsers: builder.query<User[], void>({
query: () => "users",
providesTags: (result) => [
...(result?.map((u) => ({ type: "User" as const, id: u.id })) ?? []),
{ type: "User" as const, id: "LIST" },
],
}),
}),
})Dengan satu baseQuery ber-auth (episode 17), seluruh fitur mendapat refresh token otomatis. Konsistensi pola ini yang membuat basis kode bisa dipahami tanpa membaca tiap implementasi.
Standar tim mencegah gaya kode yang berbeda-beda. Beberapa aturan yang bisa diadopsi:
1. Satu slice menangani satu domain; tambahkan slice baru, bukan
memperluas slice yang tidak relevan.
2. Gunakan createAsyncThunk untuk satu request, thunk manual untuk
alur multi-langkah (episode 12).
3. Mutation RTK Query wajib memakai tags; tidak boleh ada
refetch manual setelah mutasi.
4. Semua fetch memakai baseQuery bersama, bukan fetch langsung
di komponen.Checklist di atas diterapkan otomatis oleh linter bila memungkinkan, dan oleh code review saat tidak. Hasilnya: keputusan arsitektur tidak diulang-ulang di tiap PR.
Fokus review untuk kode Redux sebaiknya menjawab pertanyaan spesifik:
invalidatesTags yang benar?Tambahkan pertanyaan ini sebagai template PR. Mereka mengubah review dari penilaian subjektif menjadi checklist yang bisa dieksekusi semua orang.
Redux Toolkit plus react-redux menambah sekitar 14KB (gzipped) ke bundle aplikasi. Untuk aplikasi yang sangat sensitif terhadap ukuran, catat baseline dan pantau perubahannya:
npx next buildPerhatikan dua hal: redux dan react-redux hanya termuat sekali (tidak ada duplikasi akibat mix CJS/ESM), dan seluruh kode RTK memanfaatkan tree-shaking — impor seperti createSlice dibundel tanpa membawa RTK Query bila tidak dipakai.
Tree-shaking bekerja bila impor dilakukan secara named import dan bundler memakai mode production:
import { createSlice } from "@reduxjs/toolkit"
import { setupListeners } from "@reduxjs/toolkit/query"Hindari impor dari @reduxjs/toolkit/query bila hanya memakai createAsyncThunk — bundler membuang API query yang tidak terpakai, menjaga bundle tetap ramping.
Bug di production tidak bisa hanya mengandalkan konsol. Pasang error boundary untuk menangkap error render, dan kirim action error ke layanan monitoring:
import { Component } from "react"
export class ErrorBoundary extends Component {
state = { hasError: false }
static getDerivedStateFromError() {
return { hasError: true }
}
componentDidCatch(error, info) {
reportError(error, info.componentStack)
}
render() {
if (this.state.hasError) return <p>Terjadi kesalahan.</p>
return this.props.children
}
}reportError mengirim trace ke Sentry atau layanan sejenis. Kombinasikan dengan logging middleware dari episode 16 untuk melihat action terakhir sebelum crash.
Anggota baru tidak boleh menebak arsitektur. Tulis dokumentasi singkat yang menyatakan keputusan utama:
Dokumentasi ini lebih mahal untuk dirawat daripada ditulis — jaga tetap pendek dan tautkan langsung ke kode contoh, bukan paragraf panjang yang cepat basi.
Warning
Bundle size awareness tidak berarti menghindari Redux. Artinya: catat baseline, jaga tree-shaking, dan jangan import seluruh library ketika satu slice sudah cukup. Ukuran 14KB adalah harga wajar untuk debugging dan struktur yang kalian dapat.
Arsitektur produksi adalah hasil disiplin tim, bukan satu keputusan tunggal. Feature-based slices membuat kode paralel, RTK Query menjadi satu pintu server state, standar thunk dan mutation menyamakan gaya, dan code review bertanya hal yang sama di setiap PR. Dilengkapi kesadaran bundle size, error monitoring, dan onboarding docs, arsitektur Redux kalian siap dirawat bertahun-tahun.
Inti yang harus dibawa pulang:
Episode 22 — episode terakhir series ini — mengajak kalian merefleksikan perjalanan: membandingkan Redux dengan Zustand, Jotai, TanStack Query, dan Context API, menyusun decision framework 2026, serta menutup dengan rekap seluruh materi dari episode 0 sampai 21.