REACT STATE-MANAGEMENT FRONTEND WEB-DEVELOPMENT JAVASCRIPT TYPESCRIPT ZUSTAND HOOKS PERFORMANCE DEVELOPER-EXPERIENCE MODERN-WEB

Zustand: State Management Simpel dan Kuat untuk Aplikasi React Modern

⏱️ 8 menit baca
👨‍💻

Zustand: State Management Simpel dan Kuat untuk Aplikasi React Modern

1. Pendahuluan

Sebagai developer React, kita tahu bahwa mengelola state adalah salah satu tantangan terbesar dalam membangun aplikasi yang kompleks. Dari data pengguna, status loading, hingga tema aplikasi, semua perlu dikelola secara efisien agar aplikasi tetap responsif, mudah di-debug, dan scalable. Dulu, Redux menjadi solusi go-to bagi banyak orang, namun seringkali diikuti dengan boilerplate yang cukup banyak dan kurva pembelajaran yang curam.

Seiring berjalannya waktu, ekosistem React terus berevolusi, melahirkan berbagai solusi state management baru yang lebih ringan, lebih modern, dan lebih sesuai dengan paradigma hooks-based. Salah satu bintang yang bersinar terang adalah Zustand.

Zustand (yang berarti “state” dalam bahasa Jerman) adalah library state management yang minimalis namun sangat kuat, dibuat oleh tim di belakang Jotai dan React Spring. Filosofi utamanya adalah kesederhanaan dan performa. Jika Anda mencari alternatif Redux yang lebih ringkas atau ingin beralih dari Context API untuk global state yang lebih kompleks, Zustand bisa menjadi pilihan yang sangat menarik.

Artikel ini akan membawa Anda menyelami Zustand, mulai dari konsep dasarnya, cara instalasi, hingga implementasi praktis dengan contoh konkret. Mari kita permudah manajemen state Anda!

2. Mengapa Memilih Zustand? Kelebihan Utamanya

Sebelum kita masuk ke kode, mari kita pahami mengapa Zustand layak dipertimbangkan:

📌 Intinya: Jika Anda menginginkan state management yang kuat tanpa kerumitan, Zustand adalah jawabannya.

3. Instalasi dan Membuat Store Pertama Anda

Memulai dengan Zustand sangatlah mudah.

Pertama, instal library-nya:

npm install zustand
# atau
yarn add zustand

Sekarang, mari kita buat store sederhana untuk mengelola counter. Buat file src/store/counterStore.js (atau .ts jika Anda menggunakan TypeScript):

// src/store/counterStore.js
import { create } from 'zustand';

// Fungsi `create` menerima sebuah fungsi yang mengembalikan objek state dan fungsi-fungsi untuk memodifikasi state tersebut.
const useCounterStore = create((set) => ({
  count: 0, // State awal
  increment: () => set((state) => ({ count: state.count + 1 })), // Fungsi untuk menambah count
  decrement: () => set((state) => ({ count: state.count - 1 })), // Fungsi untuk mengurangi count
  reset: () => set({ count: 0 }), // Fungsi untuk mereset count
}));

export default useCounterStore;

Penjelasan:

4. Menggunakan Store di Komponen React

Setelah store dibuat, menggunakannya di komponen React Anda semudah menggunakan useState.

// src/components/CounterDisplay.jsx
import React from 'react';
import useCounterStore from '../store/counterStore';

function CounterDisplay() {
  // Hanya ambil state `count` dari store
  const count = useCounterStore((state) => state.count);

  return (
    <div style={{ padding: '10px', border: '1px solid #ccc', borderRadius: '5px' }}>
      <h3>Current Count: {count}</h3>
    </div>
  );
}

export default CounterDisplay;
// src/components/CounterControls.jsx
import React from 'react';
import useCounterStore from '../store/counterStore';

function CounterControls() {
  // Hanya ambil fungsi action `increment` dan `decrement` dari store
  const { increment, decrement, reset } = useCounterStore((state) => ({
    increment: state.increment,
    decrement: state.decrement,
    reset: state.reset,
  }));

  return (
    <div style={{ marginTop: '10px' }}>
      <button onClick={increment} style={{ marginRight: '5px' }}>Increment</button>
      <button onClick={decrement} style={{ marginRight: '5px' }}>Decrement</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

export default CounterControls;

Dan Anda bisa menggabungkannya di komponen utama Anda:

// src/App.js
import React from 'react';
import CounterDisplay from './components/CounterDisplay';
import CounterControls from './components/CounterControls';

function App() {
  return (
    <div style={{ fontFamily: 'sans-serif', padding: '20px' }}>
      <h1>Zustand Counter App</h1>
      <CounterDisplay />
      <CounterControls />
    </div>
  );
}

export default App;

💡 Tips Penting: Selector dan Re-rendering Perhatikan bagaimana kita mengambil state dari store: useCounterStore((state) => state.count);

Ini adalah selector Zustand. Ketika Anda hanya memilih sebagian dari state (misalnya, hanya count), komponen Anda hanya akan me-render ulang jika nilai count berubah. Jika ada bagian lain dari state yang berubah tapi count tidak, komponen CounterDisplay tidak akan me-render ulang. Ini adalah kunci performa Zustand!

Jika Anda mengambil seluruh state (useCounterStore((state) => state)), komponen akan me-render ulang setiap kali ada perubahan state di store, yang mungkin tidak optimal. Selalu usahakan untuk memilih hanya bagian state yang Anda butuhkan.

5. Mengelola State di Luar Komponen (Non-React)

Salah satu fitur unggulan Zustand adalah kemampuannya untuk berinteraksi dengan store di luar konteks komponen React. Ini sangat berguna untuk skenario seperti:

Anda bisa mengakses state dan action secara langsung dari store yang Anda buat:

// src/utils/logStoreState.js
import useCounterStore from '../store/counterStore';

function logCurrentCounterState() {
  // Mengakses state secara langsung (tanpa hook)
  const currentState = useCounterStore.getState();
  console.log('Current state (from outside React):', currentState.count);

  // Memanggil action secara langsung
  useCounterStore.setState({ count: currentState.count * 2 }); // Menggandakan nilai count
  console.log('State after doubling (from outside React):', useCounterStore.getState().count);
}

export default logCurrentCounterState;

Anda bisa memanggil logCurrentCounterState() dari mana saja di aplikasi Anda (misalnya, di index.js atau setelah event tertentu).

// src/App.js (contoh penggunaan)
import React, { useEffect } from 'react';
import CounterDisplay from './components/CounterDisplay';
import CounterControls from './components/CounterControls';
import logCurrentCounterState from './utils/logStoreState'; // Import utilitas kita

function App() {
  useEffect(() => {
    // Panggil fungsi utilitas setelah komponen dimount
    logCurrentCounterState();
  }, []);

  return (
    <div style={{ fontFamily: 'sans-serif', padding: '20px' }}>
      <h1>Zustand Counter App</h1>
      <CounterDisplay />
      <CounterControls />
    </div>
  );
}

export default App;

🎯 Use Case Real-world: Bayangkan Anda memiliki middleware untuk logging setiap kali state berubah, atau Anda ingin menyimpan state ke localStorage setiap kali ada perubahan. Kemampuan ini membuat Zustand sangat fleksibel.

6. Menggunakan Zustand dengan TypeScript

Zustand memiliki dukungan TypeScript yang sangat baik. Mari kita tingkatkan store counter kita dengan TypeScript untuk type safety yang lebih baik.

// src/store/counterStore.ts
import { create } from 'zustand';

// 1. Definisikan interface untuk state
interface CounterState {
  count: number;
}

// 2. Definisikan interface untuk actions
interface CounterActions {
  increment: () => void;
  decrement: () => void;
  reset: () => void;
}

// 3. Gabungkan kedua interface untuk tipe store lengkap
type CounterStore = CounterState & CounterActions;

const useCounterStore = create<CounterStore>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 }),
}));

export default useCounterStore;

Dengan TypeScript, Anda akan mendapatkan autocompletion yang lengkap dan type checking saat mengakses state atau memanggil action dari store Anda. Ini sangat membantu dalam menjaga konsistensi dan mencegah bug di aplikasi skala besar.

Kesimpulan

Zustand menawarkan pendekatan yang menyegarkan untuk state management di aplikasi React modern. Dengan API-nya yang minimalis, performa yang optimal melalui selector yang cerdas, dan fleksibilitas untuk digunakan di dalam maupun di luar komponen React, Zustand menjadi pilihan yang sangat menarik bagi developer yang mencari solusi yang lebih sederhana dan efisien dibandingkan Redux, namun lebih kuat dari Context API untuk global state yang kompleks.

Jika Anda merasa boilerplate Redux terlalu membebani atau Context API mulai terasa kurang memadai untuk kebutuhan Anda, saatnya mencoba Zustand. Anda mungkin akan terkejut betapa mudahnya mengelola state dengan library kecil namun perkasa ini!

🔗 Baca Juga