Luôn dùng selector cụ thể — gọi useStore() không selector là subscribe toàn bộ store, re-render khi bất kỳ state nào đổi.
Zustand so sánh bằng === nên selector trả primitive thì không có vấn đề; rắc rối chỉ xảy ra khi selector tạo object/array mới mỗi lần.
ts
// Zustand v5: object mới mỗi lần gọi → vòng lặp vô hạn "Maximum update depth exceeded"
const { a, b } = useStore((s) => ({ a: s.a, b: s.b }))
// cách 1 — tách thành hai selector primitive
const a = useStore((s) => s.a)
const b = useStore((s) => s.b)
// cách 2 — useShallow để so sánh nông object/array
import { useShallow } from 'zustand/react/shallow'
const { a, b } = useStore(useShallow((s) => ({ a: s.a, b: s.b })))Cách 3 là tự sinh selector cho từng property, dùng useStore.use.count() thay vì viết tay:
ts
const createSelectors = (store) => {
store.use = {}
Object.keys(store.getState()).forEach((k) => {
store.use[k] = () => store((s) => s[k])
})
return store
}