react-zustand-patterns
Zustand state management patterns for React. Use when working with Zustand stores, debugging state timing issues, or implementing async actions. Works for both React web and React Native.
Оригинален текст · няма потвърден превод на българскиПърво прочетете инструкцията.
Файлът се зарежда от посочения източник само по ваше действие. Можете да го прочетете тук, да го копирате или да го запазите като .md.
GitHub хранилище- Звезди на репото
- 428
- Лиценз
- Не е посочен. Проверете в репозитория.
- Последна проверка на записа
- Няма посочена дата
Добавете в своя инструмент.
Командата отваря избора на skills от репозитория. Прочетете файла и условията на автора преди изпълнение.
npx skills add aiskillstore/marketplaceСтраницата копира текст. Не инсталира и не изпълнява нищо на устройството ви.
Откъс от SKILL.md
Началото на файла на автора, без превод.
Zustand Patterns for React
Problem Statement
Zustand's simplicity hides important timing details. set() is synchronous, but React re-renders are batched. getState() escapes stale closures. Async actions in stores need careful handling. Understanding these internals prevents subtle bugs.
Pattern: set() is Synchronous, Renders are Batched
Problem: Assuming state is "ready" for React immediately after set().
const useStore = create((set, get) => ({
count: 0,
increment: () => {
set({ count: get().count + 1 });
// State IS updated here (set is sync)
console.log(get().count); // ✅ Shows new value
// But React hasn't re-rendered yet
// Component will see old value until next render cycle
},
}));
Key insight:
set()updates the store synchronouslygetState()immediately reflects the new value- React components re-render asynchronously (batched)
When this matters:
- Chaining multiple state updates
- Validating state after update
- Debugging "stale" component values
Pattern: getState() Escapes Stale Closures
Problem: Callbacks and async functions capture state at creation time. Using get() or getState() always gets current state.
const useStore = create((set, get) => ({
data: {},
// WRONG - closure captures stale state
saveDataBad: (id: string, value: number) => {
setTimeout(() => {
// If someone passed `data` as a parameter, it would be stale
}, 1000);
},
// CORRECT - always use get() for current state
saveData: async (id: string, value: number) => {
await someAsyncOperation();
// After await, use get() to ensure current state
const currentData = get().data;
set({ data: { ...currentData, [id]: value } });
},
}));
// In components - same principle
function Component() {
const data = useStore((s) => s.data);
const handleSave = async () => {
await delay(1000);
// data here is stale! Captured at render time
// Use getState() for current value
const current = useStore.getState().data;
};
}
Rule: After any await, use get() or getState() - never rely on closure-captured values.
Pattern: Async Actions in Stores
Problem: Async actions need explicit async/await and careful state reads after awaits.