Getter adalah computed property milik store untuk derived state. Episode ini membahas getter sederhana, getter yang mengakses state store lain, getter dengan parameter yang mengembalikan function, serta perilaku memoization yang membedakan getter tanpa argumen dengan getter berargumen.

Tidak semua nilai layak disimpan di state. Nilai yang bisa dihitung dari state lain — total harga, filter daftar, status login — sebaiknya dihitung ulang otomatis lewat getters. Ini membuat satu sumber kebenaran, dan UI tidak mungkin tidak konsisten.
Episode 6 membahas getters secara menyeluruh: getter sederhana yang mengakses state sendiri, getter yang membaca store lain, getter dengan parameter untuk pencarian dinamis, serta perilaku memoization yang sering mengejutkan.
Getter paling dasar menerima state dan mengembalikan nilai turunan:
export const useCartStore = defineStore('cart', {
state: () => ({
items: [
{ name: 'Kopi', price: 15000, qty: 2 },
{ name: 'Teh', price: 8000, qty: 1 },
],
}),
getters: {
totalItems: (state) =>
state.items.reduce((sum, item) => sum + item.qty, 0),
totalPrice: (state) =>
state.items.reduce((sum, item) => sum + item.price * item.qty, 0),
},
})state.items.reduce(...) menghitung total kuantitas dan total harga. Karena getter ini computed, nilainya di-cache dan hanya dihitung ulang saat state.items berubah — menulis ulang kalkulasi yang sama di beberapa komponen tidak perlu lagi.
Getter tidak terbatas pada state store sendiri. Kalian bisa memanggil store lain di dalam getter:
import { useUserStore } from '@/stores/user'
export const useDashboardStore = defineStore('dashboard', {
state: () => ({ greeting: 'Selamat datang' }),
getters: {
fullGreeting: (state) => {
const userStore = useUserStore()
return `${state.greeting}, ${userStore.name}!`
},
},
})useUserStore() di dalam getter terlihat seperti memanggil store di sembarang tempat, tetapi ini aman di Pinia: getter dieksekusi hanya saat store yang memanggil sudah aktif. Pola ini dipakai untuk menggabungkan data lintas store tanpa salinan.
Getter bisa menerima argumen jika mengembalikan sebuah function:
export const useProductStore = defineStore('products', {
state: () => ({
items: [
{ id: 1, name: 'Keyboard', price: 350000 },
{ id: 2, name: 'Mouse', price: 120000 },
],
}),
getters: {
findById: (state) => (id: number) =>
state.items.find((item) => item.id === id),
totalOf: (state) => (id: number) =>
state.items.filter((item) => item.id === id)
.reduce((sum, item) => sum + item.price, 0),
},
})findById: (state) => (id: number) => ... menghasilkan getter yang dipanggil seperti store.findById(2). Bentuk ini ideal untuk pencarian dinamis.
Perbedaan penting antara kedua bentuk getter:
const item2 = store.findById(2)
const item2Lagi = store.findById(2)
console.log(item2 === item2Lagi) // falseKarena store.findById(2) membuat function baru setiap akses, hasil pemanggilan adalah object baru — bukan instance yang sama. Ini biasanya bukan masalah, tetapi penting untuk disadari saat membandingkan referensi object.
Tip
Kalau getter berparameter dipakai di dalam template, nilai hasil tetap reaktif selama argumen dan state yang dibaca ikut reaktif — yang tidak di-cache hanyalah function pembungkusnya.
Episode 6 membekali kalian getters secara lengkap. Kalian sekarang bisa menulis getter sederhana, menggabungkan data dari store lain di dalam getter, membuat pencarian dinamis dengan getter berparameter, dan memahami aturan memoization keduanya.
Inti yang harus dibawa pulang:
state sebagai argumen pertama.useXStore().Di episode 7 selanjutnya kita akan membahas actions dan async logic — cara mengubah state dengan logika, action async yang memanggil API dengan status loading dan error, serta cara action memanggil store lain. Ini saatnya store berinteraksi dengan dunia luar.