State Management 2024
Legend State (signals), Nanostores (1KB), Valtio (proxy), Preact Signals i porównanie z Zustand/Jotai.
6 bibliotek state management — podejście i kiedy
Legend State, Nanostores, Valtio, Signals, Zustand i Jotai — podejście, bundle i kiedy wybrać.
| Biblioteka | Podejście | Bundle | Kiedy |
|---|---|---|---|
| Legend State | Signals + Observable | ~9KB | Performance, auto-persist, React Native |
| Nanostores | Atom + Map (1KB!) | ~1KB | Multi-framework, micro-frontends |
| Valtio | Proxy (mutowalne) | ~5KB | Intuicyjny API, prototypy |
| Preact Signals | Signals reactive | ~3KB | Granularne updates, bez observer |
| Zustand | Hooks + immutable | ~3KB | Standard 2024 — większość projektów |
| Jotai | Atoms composition | ~6KB | Złożone zależności, Recoil alternatywa |
Często zadawane pytania
Legend State — najszybszy state manager dla React?
Legend State: Jay Meistrich. Signals-based. Reactive granular updates. Automatyczna persystencja. Instalacja: npm install @legendapp/state. Podstawy: import {observable} from '@legendapp/state'. const store$ = observable({count: 0, user: {name: ''}}). Dostęp: store$.count.get() — odczyt. store$.count.set(1) — zapis. store$.count.peek() — bez subskrypcji. React: import {observer} from '@legendapp/state/react'. const Counter = observer(() => { return button onClick={() => store$.count.set(c => c + 1)} Count: {store$.count.get()} /button. }). Granular rendering: tylko komponenty subskrybujące zmienione pole re-renderują. Nie cały drzewa. Persystencja: import {persistObservable} from '@legendapp/state/persist'. persistObservable(store$, {local: 'my-store'}). Automatyczny sync z localStorage/MMKV. React Native: MMKV (szybki). Computed: import {computed} from '@legendapp/state'. const doubled$ = computed(() => store$.count.get() * 2). Reactive memoized. Sync/Async: store$.user.name.set('Jan'). Await store$.isLoaded.get(). Reactive UI pattern: zamiast useState/useEffect. Legend State = globalny reactive store. useSelector hook: import {useSelector} from '@legendapp/state/react'. const count = useSelector(store$.count). Kiedy Legend: performance critical. Persystencja automatyczna. React Native + web.
Nanostores — tiny store (1KB) dla każdego frameworka?
Nanostores: Andrey Sitnik (PostCSS twórca). 1KB. Framework-agnostic. Instalacja: npm install nanostores @nanostores/react. Atom (atomic value): import {atom} from 'nanostores'. export const count$ = atom(0). Mutacja: count$.set(count$.get() + 1). React: import {useStore} from '@nanostores/react'. const count = useStore(count$). Map (object store): import {map} from 'nanostores'. const user$ = map({name: '', email: ''}). user$.setKey('name', 'Jan'). user$.set({name: 'Jan', email: 'jan@test.pl'}). Computed (derived): import {computed} from 'nanostores'. const doubled$ = computed(count$, c => c * 2). Reactive, memoized. Action pattern: import {action} from 'nanostores'. const increment = action(count$, 'increment', (store) => { store.set(store.get() + 1) }). Czysty. Task (async action): import {task} from 'nanostores'. const loadUser = task(async () => { const data = await fetchUser(). user$.set(data) }). Batch: import {batch} from 'nanostores'. batch(() => { count$.set(1). user$.setKey('name', 'Jan') }). Vue: import {useStore} from '@nanostores/vue'. Svelte: import {useStore} from '@nanostores/svelte'. Solid: import {useStore} from '@nanostores/solid'. Sharing state: eksportuj store z pliku. Importuj wszędzie. SSR: import {keepMount} from 'nanostores'. keepMount(store$) — nie unmount między requestami. Kiedy Nanostores: micro-frontends. Multi-framework. Mały bundle critical.
Valtio — proxy-based state management dla React?
Valtio: Daishi Kato (twórca Jotai). Proxy-based reactivity. Mutuj jak zwykły obiekt. Instalacja: npm install valtio. Podstawy: import {proxy} from 'valtio'. const state = proxy({count: 0, user: {name: ''}}). Mutacja: state.count++ — bezpośrednia mutacja! state.user.name = 'Jan'. React: import {useSnapshot} from 'valtio'. function Counter() { const snap = useSnapshot(state). return div {snap.count} /div }. Granular: useSnapshot renderuje tylko gdy używane pole zmienione. Derived state: import {derive} from 'valtio/utils'. const derived = derive({doubled: get => get(state).count * 2}). Subscribe: import {subscribe} from 'valtio'. const unsub = subscribe(state, () => console.log('changed')). useSnapshot poza komponentem: const snap = snapshot(state). Serializable. DevTools: import {devtools} from 'valtio/utils'. devtools(state, {name: 'my-store', enabled: true}). Async: async function loadData() { state.loading = true. const data = await fetch('/api/data').then(r => r.json()). state.data = data. state.loading = false. }. Ref (non-reactive): import {ref} from 'valtio'. state.canvas = ref(canvasElement). Nie trackuje. proxyWithHistory: import {proxyWithHistory} from 'valtio/utils'. undo/redo wbudowany. proxySet/proxyMap: reaktywne kolekcje. Valtio vs Zustand: Valtio — mutuj bezpośrednio, proxy magic. Zustand — immutable setter. Valtio — intuicyjny dla JS devów. Kiedy Valtio: prototypy. Proste state. Nie lubisz immutability.
Signals w React — @preact/signals-react i Alien Signals?
Signals koncepcja: granularne reaktywne wartości. Bez re-render całego drzewa. Subskrypcja per-wartość. Preact Signals: @preact/signals-react — React adapter. Instalacja: npm install @preact/signals-react. import {signal, computed, effect} from '@preact/signals-react'. const count = signal(0). const doubled = computed(() => count.value * 2). React component: function App() { return button onClick={() => count.value++} {count} /button. }. Nie useSnapshot ani observer — auto! effect(() => { console.log('count changed:', count.value) }). Ograniczenia: wymaga babel/swc transform. Nie w Next.js App Router bez konfiguracji. Alien Signals: nowa biblioteka 2024. Najszybsze signals. Vue Vapor używa. SolidJS model. TC39 Signals Proposal: standardowe signals w JS. Proposal Stage 1. Polyfill: signal-polyfill. Compatibility layer dla frameworków. Angular Signals (stable): Angular 17+. import {signal, computed, effect} from '@angular/core'. const count = signal(0). const doubled = computed(() => count() * 2). count.set(1). count.update(c => c + 1). Reactive forms: model inputs. Two-way binding z signals. SolidJS signals (native): createSignal, createEffect, createMemo. Najdojrzalszy model signals. Qwik signals: useSignal, useStore. Resume-ability + signals. Signals vs useState: useState — React re-render tree. signal — granularne, żaden re-render parent. Signals przyszłość? TC39 Proposal sugeruje tak.
Porównanie Zustand, Jotai, Legend State, Nanostores i Valtio?
Zustand (lider 2024): Daishi Kato. Prosty. Hooks-based. Immutable updates. Bundle: ~3KB. Najszerszy ekosystem. Middleware: devtools, persist, immer. Kiedy: większość projektów. Standard 2024. Jotai (atom model): Daishi Kato. React-first. Atom composition. Bundle: ~6KB. Atomic state. Recoil-like ale prostszy. Kiedy: złożona, powiązana state. Derive chains. Legend State (signals): Jay Meistrich. Najszybszy update. Persystencja. Bundle: ~9KB. Kiedy: performance critical. React Native + web. Nanostores (micro): Andrey Sitnik. Framework-agnostic. 1KB. Kiedy: multi-framework, micro-frontend. Valtio (proxy): Daishi Kato. Mutable API. Bundle: ~5KB. Kiedy: prototypy, prosty state. XState (machines): David Khourshid. State machines. Bundle: ~15KB. Kiedy: kompleksowa logika. Formularz wieloetapowy. Redux Toolkit (enterprise): standardowy Redux. Duże projekty. DevTools best. Wybór 2024: nowy projekt React -- Zustand. Atomowe zależności -- Jotai. Multi-framework -- Nanostores. Performance + persist -- Legend State. Mutable syntax -- Valtio. Complex flows -- XState. Bundle size comparison: Nanostores: 1KB. Zustand: 3KB. Valtio: 5KB. Jotai: 6KB. Legend State: 9KB. XState: 15KB.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz