createProvider
创建组件隔离的 store,适用于局部状态管理
何时使用 Provider
适用于需要按组件实例隔离的状态:
- 模态框或对话框状态
- 不应持久化的表单状态
- 不应全局化的功能特定状态
API 参考
语法
const [Provider, useFindStore, storeActions] = createProvider(initialState);
参数
initialState
: 定义 store 初始状态和操作的对象
返回值
包含以下内容的元组:
Provider
: 为子组件提供隔离 store 实例的 React 组件useFindStore
: 在 provider 树中访问 store 实例的 hookstoreActions
: 包含getStore
、getState
、setState
方法的工具对象
示例
简单隔离状态
import { createProvider, useStoreValue } from "zenbox";
// 为每个 provider 创建隔离的会话状态
const [SessionProvider, useFindSessionStore] = createProvider({
user: null,
isAuthenticated: false,
sessionId: null,
preferences: {
theme: "light",
language: "zh",
},
});
function UserProfile() {
const store = useFindSessionStore();
const { user, isAuthenticated } = useStoreValue(store);
if (!isAuthenticated) {
return <div>请登录</div>;
}
return (
<div>
<h1>欢迎,{user.name}!</h1>
<p>会话ID: {store.value.sessionId}</p>
</div>
);
}
function App() {
return (
<SessionProvider initialState={{ sessionId: "abc123" }}>
<UserProfile />
</SessionProvider>
);
}
带操作的 Provider
const [GameProvider, useFindGameStore, gameActions] = createProvider({
// 状态
score: 0,
level: 1,
lives: 3,
gameState: "playing" as "playing" | "paused" | "gameOver",
// 操作
increaseScore(points) {
gameActions.setState((state) => {
state.score += points;
// 每1000分自动升级
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}</span>
<span>等级: {level}</span>
<span>生命: {lives}</span>
</div>
{gameState === "gameOver" ? (
<div className="game-over">
<h2>游戏结束!最终得分: {score}</h2>
<button onClick={store.value.resetGame}>重新开始</button>
</div>
) : (
<div className="game-area">
<button onClick={() => store.value.increaseScore(100)}>
+100 分
</button>
<button onClick={store.value.loseLife}>失去生命</button>
</div>
)}
</div>
);
}
// 多个独立的游戏实例
function App() {
return (
<div className="app">
<h1>游戏竞技场</h1>
<div className="games">
<GameProvider>
<h2>玩家 1</h2>
<GameComponent />
</GameProvider>
<GameProvider>
<h2>玩家 2</h2>
<GameComponent />
</GameProvider>
</div>
</div>
);
}
嵌套 Provider
function App() {
return (
<SessionProvider>
<GameProvider>
<GameComponent />
</GameProvider>
</SessionProvider>
);
}
Provider vs 全局 Store
特性 | createProvider | createStore |
---|---|---|
作用域 | 组件树 | 全局应用 |
隔离性 | ✅ 完全隔离 | ❌ 应用间共享 |
上下文 | ✅ React Context | ❌ 直接访问 |
多实例 | ✅ 独立 | ❌ 单一实例 |
适用于 | 模态框、表单、组件 | 应用状态、用户数据 |
最佳实践
✅ 用于真正隔离的状态
// Good:弹窗状态不应在实例间共享
const [ModalProvider, useModal] = createProvider({
isOpen: false,
step: 1,
});
✅ 使用有意义的默认值初始化
<GameProvider initialState={{
difficulty: "hard",
playerName: "匿名"
}}>
✅ 保持 provider 专注
// Good:单一职责
const [FormProvider, useForm] = createProvider({
values: {},
errors: {},
isSubmitting: false,
});
❌ 不要用于全局状态
// Bad:用户认证应该是全局的,无需使用 provider 隔离
const [AuthProvider] = createProvider({
currentUser: null,
});
相关 API
createStore
- 全局 store 创建useStoreValue
- 同步 store 最新状态useComputed
- 响应式更新的计算值