createProvider
Create isolated, component-scoped stores with React Context integration
When to Use Providers
Perfect for state that should be isolated per component instance:
- Modal or dialog state
- Form state that shouldn't persist
- Tab or accordion panel state
- Feature-specific state that shouldn't be global
API Reference
Syntax
const [Provider, useFindStore, storeActions] = createProvider(initialState);
Parameters
initialState
: Object defining the store's initial state and actions
Returns
A tuple containing:
Provider
: React component that provides isolated store instance to childrenuseFindStore
: Hook to access the store instance within provider treestoreActions
: Utility object withgetStore
,getState
,setState
methods
Examples
Simple Isolated State
import { createProvider, useStoreValue } from "zenbox";
// Create isolated session state per provider
const [SessionProvider, useFindSessionStore] = createProvider({
user: null,
isAuthenticated: false,
sessionId: null,
preferences: {
theme: "light",
language: "en",
},
});
function UserProfile() {
const store = useFindSessionStore();
const { user, isAuthenticated } = useStoreValue(store);
if (!isAuthenticated) {
return <div>Please log in</div>;
}
return (
<div>
<h1>Welcome, {user.name}!</h1>
<p>Session: {store.value.sessionId}</p>
</div>
);
}
function App() {
return (
<SessionProvider initialState={{ sessionId: "abc123" }}>
<UserProfile />
</SessionProvider>
);
}
Provider with Actions
const [GameProvider, useFindGameStore, gameActions] = createProvider({
// State
score: 0,
level: 1,
lives: 3,
gameState: "playing" as "playing" | "paused" | "gameOver",
// Actions
increaseScore(points) {
gameActions.setState((state) => {
state.score += points;
// Auto level-up every 1000 points
if (state.score >= state.level * 1000) {
state.level += 1;
}
});
},
loseLife() {
gameActions.setState((state) => {
state.lives -= 1;
if (state.lives <= 0) {
state.gameState = "gameOver";
}
});
},
resetGame() {
gameActions.setState((state) => {
state.score = 0;
state.level = 1;
state.lives = 3;
state.gameState = "playing";
});
},
});
function GameComponent() {
const store = useFindGameStore();
const { score, level, lives, gameState } = useStoreValue(store);
return (
<div className="game">
<div className="hud">
<span>Score: {score}</span>
<span>Level: {level}</span>
<span>Lives: {lives}</span>
</div>
{gameState === "gameOver" ? (
<div className="game-over">
<h2>Game Over! Final Score: {score}</h2>
<button onClick={store.value.resetGame}>Play Again</button>
</div>
) : (
<div className="game-area">
<button onClick={() => store.value.increaseScore(100)}>
+100 Points
</button>
<button onClick={store.value.loseLife}>Lose Life</button>
</div>
)}
</div>
);
}
// Multiple independent game instances
function App() {
return (
<div className="app">
<h1>Game Arena</h1>
<div className="games">
<GameProvider>
<h2>Player 1</h2>
<GameComponent />
</GameProvider>
<GameProvider>
<h2>Player 2</h2>
<GameComponent />
</GameProvider>
</div>
</div>
);
}
Nested Providers
function App() {
return (
<SessionProvider>
<GameProvider>
<GameComponent />
</GameProvider>
</SessionProvider>
);
}
Provider vs Global Store
Feature | createProvider | createStore |
---|---|---|
Scope | Component tree | Global application |
Isolation | ✅ Perfect isolation | ❌ Shared across app |
Context | ✅ React Context | ❌ Direct access |
Multiple instances | ✅ Independent | ❌ Single instance |
Best for | Modals, forms, widgets | App state, user data |
Best Practices
✅ Use for truly isolated state
// Good: Modal state shouldn't leak between instances
const [ModalProvider, useModal] = createProvider({
isOpen: false,
step: 1,
});
✅ Initialize with meaningful defaults
<GameProvider initialState={{
difficulty: "hard",
playerName: "Anonymous"
}}>
✅ Keep providers focused
// Good: Single responsibility
const [FormProvider, useForm] = createProvider({
values: {},
errors: {},
isSubmitting: false,
});
❌ Don't use for global state
// Bad: User auth should be global, not per-provider
const [AuthProvider] = createProvider({
currentUser: null, // This should be global!
});
Related APIs
createStore
- Global store creationuseStoreValue
- Subscribe to store changesuseComputed
- Derived reactive values