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.
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.
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
# Menggunakan NPM
npm install zustand
Implementasi useState vs Zustand
Mengubah state menggunakan useState Hooks
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.
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>
)
}
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
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
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.
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
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.
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;
Membuat Layout Home
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>
)
}
Membuat Button Decrement Component
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
Membuat Button Increment Component
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
Hanya dengan menggunakan 1 baris kode ini
const counter = useCounter();
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)