DEV Community

Cover image for Menggunakan Zustand Sebagai State Management pada React/Next JS.
Yoga Meleniawan Pamungkas
Yoga Meleniawan Pamungkas

Posted on • Edited on

Menggunakan Zustand Sebagai State Management pada React/Next JS.

Image description

Pengelolaan state pada React JS atau Next JS tentunya adalah hal yang perlu kita perhatikan. Karena manajemen state merupakan salah satu hal yang cukup krusial dalam pengembangan aplikasi. Tentunya, sekarang kita akan coba sedikit berkenalan dengan Zustand yang memiliki deskripsi “A small, fast and scalable bearbones state-management solution using simplified flux principles. Has a comfy API based on hooks, isn’t boilerplatey or opinionated.”.

Tetapi sebelum kita masuk lebih dalam. Kita akan coba sedikit belajar bersama, kenapa state management itu diperlukan. Jika teman-teman sudah pernah membuat page dengan banyak component dan memiliki deep level of component pasti pernah merasakan hal yang cukup meresahkan. Dikarenakan ada case condition tertentu yang mengharuskan mengubah state dari grandchild ke parent. Jika teman-teman mengubah state dari grandchild ke parent dengan mengirimkan state dari parent → child → grandchild. Selamat anda masuk ke dalam kategori developer yang mengimplementasikan Props Drilling. Apakah ini sebuah pencapaian? tentu saja bukan, ini termasuk ke dalam kategori developer yang suka membuat ribet diri sendiri.

Image description

Maka dengan permasalahan props drilling ini kita perlu menyelesaikan masalah tersebut dengan state management. Tapi perlu diketahui banyak sekali jenis-jenis state management yang bisa teman-teman gunakan selain Zustand yaitu Redux, Recoil, atau Jotai. Apakah Zustand lebih baik daripada state management yang lain? tentu saja jawabannya tidak. Dikarenakan masing-masing state management pasti punya kelebihan dan kekurangan masing-masing. Sehingga, kita perlu memilih dan menggunakan state management yang sesuai dengan kebutuhan aplikasi yang kita kembangkan.

Image description


Persiapan

Sebelum mempelajari lebih lanjut pastikan sudah pernah tau tentang context yang ada pada React JS. Saya berasumsi teman-teman pasti sudah tau tentang context dikarenakan sudah pernah dibahas pada sharing session.

Instalasi Zustand

Jalankan perintah berikut untuk melakukan instalasi Zustand :

# Menggunakan yarn
yarn add zustand
Enter fullscreen mode Exit fullscreen mode
# Menggunakan NPM
npm install zustand
Enter fullscreen mode Exit fullscreen mode

Implementasi useState vs Zustand

Mengubah state menggunakan useState Hooks

Image description

Kita akan membuat tampilan seperti diatas dengan 3 komponen utama yaitu menampilkan total number, button increment, dan button decrement. Lalu kita akan melakukan passing useState hooks yang didefinisikan pada layout page Home.

Image description

Kode program :

"use client"
import { useState } from 'react'
import ButtonIncrement from './components/ButtonIncrement';
import ButtonDecrement from './components/ButtonDecrement';

export default function Home() {
  const [count, setCount] = useState(0);
  return (
    <main className="flex flex-col items-center justify-center min-h-screen">
      <div>COUNT: {count}</div>
      <div className="flex flex-row my-2">
        <ButtonDecrement count={count} setCount={setCount} />
        <ButtonIncrement count={count} setCount={setCount} />
      </div>
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

Image description

Kode program :

import React, { Dispatch } from 'react'

interface Props { count: number; setCount: Dispatch<number> }
const ButtonDecrement = ({ count, setCount }: Props) => {
    return (
        <>
            <button 
                className="bg-white text-black rounded-sm px-2 py-2 mx-2" 
                onClick={() => setCount(count - 1)}>Decrement : {count}
            </button>
        </>
    )
}
export default ButtonDecrement
Enter fullscreen mode Exit fullscreen mode

Image description

Kode program :

import React, { Dispatch } from 'react'

interface Props { count: number; setCount: Dispatch<number> }
const ButtonIncrement = ({ count, setCount }: Props) => {
   return (
      <>
         <button
            className="bg-white text-black rounded-sm px-2 py-2 mx-2"
            onClick={() => setCount(count + 1)}>Increment : {count}
            </button>
      </>
   )
}
export default ButtonIncrement
Enter fullscreen mode Exit fullscreen mode

Dari kode program diatas apakah ada yang salah? jawabannya tidak ada. Tapi kalau pertanyaannya kita ubah menjadi, apakah kode program tersebut efektif untuk mengembangkan aplikasi dengan multi-level component yang banyak? jawabannya tidak efektif.

Image description

Kita bisa melihat gambar diatas untuk menggambarkan multi-level component yang dimaksud sebelumnya. Jika kita mengirimkan useState hooks dari parent ke grandchild maka, ini sesuai dengan yang dimaksud props drilling pada penjelasan sebelumnya. Jadi, ketika kita ingin mengubah state yang ada pada komponen keranjang misalkan seperti gambar diatas, maka kita juga perlu mengirim state dari komponen tambah keranjang ke komponen keranjang ketika tidak menggunakan state management, cukup ribet kan?

Mengubah state menggunakan Zustand

Image description

Kita akan membuat tampilan seperti diatas dengan 3 komponen utama yaitu menampilkan total number, button increment, dan button decrement. Lalu kita akan mendefinisikan store yang akan di-consume oleh component yang membutuhkan.

Membuat File Store

Kita akan membuat store yang akan digunakan di berbagai macam komponen yang membutuhkannya. Untuk penamaan useCounter merupakan penamaan yang bebas, jadi bisa disesuaikan dengan kebutuhan.

Image description

Kode program:

import create from "zustand";

interface CounterState {
    count: number;
    increment: () => void;
    decrement: () => void;
}
const useCounter = create<CounterState>((set) => ({
    count: 0,
    increment: () => set((state) => ({ count: state.count + 1 })),
    decrement: () => set((state) => ({ count: state.count - 1 })),
}));
export default useCounter;
Enter fullscreen mode Exit fullscreen mode

Membuat Layout Home

Image description

Kode program:

"use client"
import ButtonIncrement from './components/ButtonIncrement';
import ButtonDecrement from './components/ButtonDecrement';
import useCounter from './stores/store';

export default function Home() {
  const counter = useCounter();
  return (
    <main className="flex flex-col items-center justify-center min-h-screen">
      <div>COUNT: {counter.count}</div>
      <div className="flex flex-row my-2">
        <ButtonDecrement />
        <ButtonIncrement />
      </div>
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

Membuat Button Decrement Component

Image description

Kode program:

import React from 'react'
import useCounter from '../stores/store';

const ButtonDecrement = () => {
    const counter = useCounter();
    return (
        <>
            <button
                className="bg-white text-black rounded-sm px-2 py-2 mx-2"
                onClick={counter.decrement}>Decrement : {counter.count}
            </button>
        </>
    )
}
export default ButtonDecrement
Enter fullscreen mode Exit fullscreen mode

Membuat Button Increment Component

Image description

Kode program:

import React, { Dispatch } from 'react'
import useCounter from '../stores/store';

const ButtonIncrement = () => {
 const counter = useCounter();
 return (
  <>
   <button
    className="bg-white text-black rounded-sm px-2 py-2 mx-2"
    onClick={counter.increment}>Increment : {counter.count}
   </button>
  </>
 )
}
export default ButtonIncrement
Enter fullscreen mode Exit fullscreen mode

Hanya dengan menggunakan 1 baris kode ini

const counter = useCounter();

Enter fullscreen mode Exit fullscreen mode

yang mana useCounter(); ini merupakan store yang sudah kita definisikan sebelumnya. Kita sudah bisa mengubah state dari komponen yang menggunakannya tanpa memperhatikan deep level of component-nya.

Kesimpulan

Dengan menggunakan Zustand sebagai state management, kita bisa melihat perbedaan yang cukup signifikan antara penggunaan useState Hooks dan Zustand ketika mengubah sebuah state. Perbedaan yang cukup terlihat yaitu penggunaan Zustand jauh lebih efektif dan fleksibel, karena kita hanya perlu mendefinisikan store kemudian bisa digunakan di berbagai macam component tanpa memperhatikan deep level of component-nya. Tapi, jika skalabilitas aplikasi yang dikembangkan cukup kompleks maka, ada rekomendasi lain sebagai state management yaitu Redux Toolkit yang mana sejauh ini beberapa aplikasi yang mempunyai skalabilitas cukup kompleks masih menggunakan Redux dibandingkan Zustand.

Top comments (0)