webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
State management · Lecția 3 din 4

Zustand

Store global minimalist: create, set cu merge, selectori, persist.

Actualizat

Ce este Zustand

Zustand e o librărie mică (~1 KB) pentru state global: un store creat cu o funcție, folosit ca un hook. Fără provider, fără acțiuni de tip string, fără reduceri — doar state și funcții care îl modifică.

import { create } from 'zustand'

type CartState = {
  items: number[]
  add: (id: number) => void
  clear: () => void
}

export const useCart = create<CartState>()(set => ({
  items: [],
  add: id => set(state => ({ items: [...state.items, id] })),
  clear: () => set({ items: [] }),
}))
'use client'
const count = useCart(state => state.items.length)   // selector
const add = useCart(state => state.add)
<button onClick={() => add(product.id)}>Adaugă</button>

Cum funcționează

  • create returnează un hook. Store-ul trăiește în afara React-ului; componentele se abonează la el.
  • set combină (merge) obiectul nou cu state-ul existent, pe primul nivel — nu trebuie să copiezi tot.
  • Componenta se re-randează doar când valoarea întoarsă de selector se schimbă.

Selectorii — cel mai important detaliu

Cod Re-randare când
useCart() (fără selector) orice se schimbă în store ✗
useCart(s => s.items.length) doar când se schimbă numărul ✓
useCart(s => ({ a: s.a, b: s.b })) mereu — obiect nou la fiecare randare ✗
useCart(useShallow(s => ({ a: s.a, b: s.b }))) când a sau b se schimbă ✓

Regula: selectează cât mai puțin; pentru mai multe valori, mai multe apeluri sau useShallow.

Middleware utile

import { persist, devtools } from 'zustand/middleware'

export const useSettings = create<Settings>()(
  persist(
    set => ({ theme: 'light', setTheme: theme => set({ theme }) }),
    { name: 'settings' },                 // cheia din localStorage
  ),
)
Middleware Ce face
persist salvează store-ul în localStorage / sessionStorage
devtools conectează la Redux DevTools
immer sintaxă „mutabilă”, ca în RTK

Zustand vs Redux Toolkit

Zustand Redux Toolkit
Cod pentru un store simplu ~10 linii slice + store + provider + hook-uri tipate
Provider nu e nevoie da
Structură impusă puțină — tu decizi multă — slice-uri, acțiuni
Server state nu (folosește TanStack Query) RTK Query inclus
Potrivit majoritatea aplicațiilor aplicații mari, echipe care vor reguli stricte

Zustand cu Next.js

Un store global de modul e partajat pe server între request-uri. Reguli:

  • Folosește store-ul doar în Client Components.
  • Nu pune în el date specifice unui user la randarea pe server; pentru asta, creează store-ul per request (createStore + Context) — ghidul oficial descrie pattern-ul.
  • Pentru persist, valoarea din localStorage apare abia după hidratare.

Unde stă în FSD

Store legat de o entitate → entities/cart/model/cart-store.ts. Store de UI global → shared/model/ sau slice-ul care îl deține.

Pe scurt

  • Zustand = create → hook; set face merge; fără provider.
  • Selectori mici; useShallow pentru mai multe valori.
  • persist pentru localStorage; în Next doar pe client, atenție la date per user.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.