usePick
按需订阅 store 指定状态变化
为什么使用 usePick?
专为性能优化而设计 - 仅在实际使用的特定属性发生变化时才重新渲染。
性能比较
const userStore = createStore({
name: "张三",
age: 30,
email: "zhangsan@example.com",
avatar: "avatar.jpg",
preferences: { theme: "dark", language: "zh" },
lastLogin: new Date(),
});
// ❌ Bad:任何 store 状态变化都会触发重新渲染
function UserName() {
const user = useStoreValue(userStore);
return <h1>{user.name}</h1>; // 仅使用 name,但订阅了所有状态
}
// ✅ Good:仅在 name 变化时重新渲染
function OptimizedUserName() {
const { name } = usePick(userStore, "name");
return <h1>{name}</h1>; // 只订阅需要的属性
}
API 参考
语法
const selectedFields = usePick(store, ...keys);
const selectedFields = usePickDeeply(store, ...keys); // 深度相等检查
参数
store
: ZenBox store 实例...keys
: 要从 store 中选择的属性名称
返回值
仅包含从 store 中选择的属性的对象。
示例
单个属性
function UserName() {
// 仅在 name 变化时重新渲染
const { name } = usePick(userStore, "name");
return <h1>{name}</h1>;
}
多个属性
function UserContact() {
// 仅在 name 或 email 变化时重新渲染
const { name, email } = usePick(userStore, "name", "email");
return (
<div>
<h2>{name}</h2>
<p>邮箱: {email}</p>
</div>
);
}
深度比较
对于需要深度比较的嵌套对象:
const settingsStore = createStore({
theme: {
colors: { primary: "#blue", secondary: "#gray" },
fonts: { heading: "Arial", body: "Helvetica" },
},
notifications: {
email: true,
push: false,
},
});
function ThemeSettings() {
// 启用深度比较,避免不必要的重新渲染
const { theme } = usePickDeeply(settingsStore, "theme");
return (
<div
style={{
color: theme.colors.primary,
fontFamily: theme.fonts.heading,
}}
>
当前主题配置
</div>
);
}
usePick vs useStoreValue
方法 | 代码 | 性能 |
---|---|---|
usePick | usePick(store, "name", "email") | ✅ 最佳 - 仅特定属性 |
useStoreValue + pick | useStoreValue(store, { pick: ["name", "email"] }) | ✅ 相同性能,更冗长 |
useStoreValue | useStoreValue(store) | ❌ 任何变化都会重新渲染 |
最佳实践
✅ 明确属性选择
// ❌ Bad:不选择任何属性(等同于 useStoreValue)
const { name } = usePick(userStore);
// ❌ Bad:选择太多属性
const { name } = usePick(userStore, "name", "age", "email", "avatar");
// ✅ Good:仅选择所需属性
const { name, status } = usePick(userStore, "name", "status");
✅ 将相关属性分组
// ❌ Bad:过于细粒度
const { name } = usePick(userStore, "name");
const { email } = usePick(userStore, "email");
const { age } = usePick(userStore, "age");
// ✅ Good:分组相关属性
const { name, email, age } = usePick(userStore, "name", "email", "age");
相关 Hook
useStoreValue
- 同步 store 最新状态useComputed
- 响应式更新的计算值useWatch
- 监听状态变化并执行副作用