Implementasi useReducerAtom Jotai
Haikel, 3 min read / May 29, 2023
بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ
Pendahuluan
useReducer
adalah sebuah React Hook yang fungsinya serupa dengan useState
, tapi biasa digunakan untuk kasus yang lebih kompleks, juga cara penggunaannya yang berbeda.
Di jotai juga, punya hal serupa yang bernama useReducerAtom
. Konsepnya sama saja dengan useReducer
biasa, hanya saja initialState ama reducernya dibalik.
Jadi kurang lebih begini gambarannya:
const [state, dispatch] = useReducerAtom(initialAtom, reducer);
Nah jadi si initialState nya(dalam hal ini initialAtom) berada di depan, kemudian diikuti dengan fungsi reducer nya. initialState mesti bernilai atom yang disediakan jotai. Kalau temen-temen pake typescript, pasti bakal ngedetect Error jika tidak pakai atom. Contoh:
Padahal jika saya pakai useReducer
biasa, dia ga bakal error
Implementasi
Disini saya coba implementasi ke operasi matematika sederhana(tambah, kurang). Sebagai catatan, di project saya sudah terinstall chakra-ui
untuk styling. Emang Overkill sih hehe, tapi kalo buat keperluan ngetest doang mah gapapa.
import { Button, Container, Flex, Text } from "@chakra-ui/react";
import { atom } from "jotai";
import { useReducerAtom } from "jotai/utils";
function reducer(state: { value: number }, action: { operation: "TAMBAH" | "KURANG" }) {
switch (action.operation) {
case "TAMBAH":
return {
value: state.value + 1,
};
case "KURANG":
return {
value: state.value - 1,
};
default:
throw new Error();
}
}
const reducerAtom = atom<{ value: number }>({ value: 0 });
Fokus di bagian fungsi reducer
, saya pakai switch case untuk pengkondisian. Pake if else juga bisa.
- Jika
operation
nya bernilai "TAMBAH", maka nilai akan bertambah 1. - Jika
operation
nya bernilai "KURANG", maka nilai akan berkurang 1. - Jika nilainya selain itu, maka akan mencetak pesan Error.
Saya juga menginisialisasi reducerAtom
sebagai initialAtom.
Oke mari kita lanjut
export default function App() {
const [state, dispatch] = useReducerAtom(reducerAtom, reducer);
return (
<Container>
<Flex justify="center" h="100vh" alignItems="center" flexDir="column">
<Flex gap={3}>
<Button onClick={() => dispatch({ operation: "TAMBAH" })}>+</Button>
<Text>{state.value}</Text>
<Button onClick={() => dispatch({ operation: "KURANG" })}>-</Button>
</Flex>
</Flex>
</Container>
);
}
Seperti yang sudah saya singgung di awal, useReducerAtom
agak berbeda dengan useReducer
biasa. Di dalam useReducerAtom
, kita memasukkan nilai reducerAtom
dan fungsi reducer
.
Keseluruhan code:
import { Button, Container, Flex, Text } from "@chakra-ui/react";
import { atom } from "jotai";
import { useReducerAtom } from "jotai/utils";
function reducer(state: { value: number }, action: { operation: "TAMBAH" | "KURANG" }) {
switch (action.operation) {
case "TAMBAH":
return {
value: state.value + 1,
};
case "KURANG":
return {
value: state.value - 1,
};
default:
throw new Error();
}
}
const reducerAtom = atom<{ value: number }>({ value: 0 });
export default function App() {
const [state, dispatch] = useReducerAtom(reducerAtom, reducer);
return (
<Container>
<Flex justify="center" h="100vh" alignItems="center" flexDir="column">
<Flex gap={3}>
<Button onClick={() => dispatch({ operation: "TAMBAH" })}>+</Button>
<Text>{state.value}</Text>
<Button onClick={() => dispatch({ operation: "KURANG" })}>-</Button>
</Flex>
</Flex>
</Container>
);
}
Jika dijalankan, maka akan seperti ini:
Penutup
Yep, mungkin sekian untuk tulisan kali ini. Semoga bermanfaat :)