On this Page
- Why Subscribe Outside React?
- Using
.subscribe()on a Store - Example: Syncing to Local Storage
- Unsubscribing and Cleanup
- Best Practices and Pitfalls
On this Guide
- Lesson 09: Organizing State with Slices and Modular Stores
- Lesson 10: Persisting State to localStorage or sessionStorage
- Lesson 11: Using Devtools Middleware for Debugging
- Lesson 12: Using Zustand with Immer for Immutable Updates
- Lesson 13: Using Zustand with Middleware: Logging, Tracking, and Side Effects
- Lesson 14: Subscribing to External State Changes
- Lesson 15: Creating Read-Only or Transient State Stores
- Lesson 16: Testing Zustand Stores with React Testing Library
- Lesson 17: Using Zustand in Server-Side Rendering (Next.js)
Why Subscribe Outside React?
Sometimes you need to run side effects whenever a store changes, even outside the React tree. Common use cases:
- Save data to
localStoragemanually - Trigger analytics events
- Log transitions or track sessions
Zustand exposes a .subscribe() method for this.
Using .subscribe() on a Store
You can subscribe to the entire state:
const unsub = useStore.subscribe((state) => {
console.log("New state:", state);
});
Or subscribe to a slice:
const unsub = useStore.subscribe(
(state) => state.count,
(count, prevCount) => {
console.log("Count changed:", prevCount, "→", count);
}
);
This works outside React, including in main.ts, useEffect(), or Node contexts.
Example: Syncing to Local Storage
useCounterStore.subscribe((state) => {
localStorage.setItem("count", String(state.count));
});
This allows manual persistence for very specific cases, without using persist().
Unsubscribing and Cleanup
Store the returned function to clean up:
const unsub = useStore.subscribe(...);
unsub(); // stop listening
If used in useEffect, be sure to return it:
useEffect(() => {
const unsub = useStore.subscribe(...);
return unsub;
}, []);
Best Practices and Pitfalls
✅ Use subscriptions for:
- Analytics
- Logging
- Manual persistence
- Live sync (WebSocket, Firebase)
🚫 Avoid:
- UI updates or state branching inside subscribers
- Mutating state in response to state (causes loops!)
Summary
- Zustand supports external subscriptions to state
- Useful for non-UI side effects like analytics or persistence
- Always unsubscribe to avoid memory leaks
- Avoid doing complex state logic inside subscribers
Next: Lesson 15 – Creating Read-Only or Transient State Stores