zustand by lobehub/lobe-chat
npx skills add https://github.com/lobehub/lobe-chat --skill zustandUI 组件使用的主要接口:
createTopic、sendMessage)internal_*)核心业务逻辑实现:
internal_ 前缀(internal_createTopic)internal_dispatch*)状态更新处理器:
internal_dispatch + 实体()广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
internal_dispatchTopicset使用 Reducer 模式:
messagesMap、topicMaps)使用简单 set:
internal_createTopic: async (params) => {
const tmpId = Date.now().toString();
// 1. 立即更新前端(乐观)
get().internal_dispatchTopic(
{ type: 'addTopic', value: { ...params, id: tmpId } },
'internal_createTopic'
);
// 2. 调用后端服务
const topicId = await topicService.createTopic(params);
// 3. 刷新以确保一致性
await get().refreshTopic();
return topicId;
},
删除操作:不要使用乐观更新(破坏性操作,恢复复杂)
操作:
createTopic、sendMessageinternal_createTopic、internal_updateMessageContentinternal_dispatchTopicinternal_toggleMessageLoading状态:
messageLoadingIds、topicEditingIdstopicMaps、messagesMapactiveTopicIdtopicsInitreferences/action-patterns.mdreferences/slice-organization.md我们正在将切片从普通的 StateCreator 对象迁移到基于类的操作。
定义一个类来封装操作,并在构造函数中接收 (set, get, api)。
使用 #private 字段(例如 #set、#get)以避免内部泄漏。
优先使用共享的类型辅助工具:
StoreSetter<T> 来自 @/store/types 用于 set。Pick<ActionImpl, keyof ActionImpl> 以仅公开公共方法。导出一个 create*Slice 辅助函数,返回一个类实例。
type Setter = StoreSetter<HomeStore>; export const createRecentSlice = (set: Setter, get: () => HomeStore, _api?: unknown) => new RecentActionImpl(set, get, _api);
export class RecentActionImpl { readonly #get: () => HomeStore; readonly #set: Setter;
constructor(set: Setter, get: () => HomeStore, _api?: unknown) { void _api; this.#set = set; this.#get = get; }
useFetchRecentTopics = () => { // ... }; }
export type RecentAction = Pick<RecentActionImpl, keyof RecentActionImpl>;
在 store 文件中,使用 flattenActions 合并类实例(不要直接展开类实例)。
flattenActions 将方法绑定到原始类实例,并支持原型方法和类字段。
const createStore: StateCreator<HomeStore, [['zustand/devtools', never]]> = (...params) => ({ ...initialState, ...flattenActions<HomeStoreAction>([ createRecentSlice(...params), createHomeInputSlice(...params), ]), });
对于需要多个操作类的大型切片,在切片入口处使用 flattenActions 组合它们。
如果需要组合多个类并隐藏私有字段,可以使用本地的 PublicActions<T> 辅助工具。
type PublicActions<T> = { [K in keyof T]: T[K] };
export type ChatGroupAction = PublicActions< ChatGroupInternalAction & ChatGroupLifecycleAction & ChatGroupMemberAction & ChatGroupCurdAction
;
export const chatGroupAction: StateCreator< ChatGroupStore, [['zustand/devtools', never]], [], ChatGroupAction
= (...params) => flattenActions<ChatGroupAction>([ new ChatGroupInternalAction(...params), new ChatGroupLifecycleAction(...params), new ChatGroupMemberAction(...params), new ChatGroupCurdAction(...params), ]);
ChatGroupStoreWithSwitchTopic 用于生命周期 switchTopicChatGroupStoreWithRefresh 用于成员刷新ChatGroupStoreWithInternal 用于 curd internal_dispatchChatGroupStateCreator 参数 (set, get, api) 对齐。#private 以避免 set/get 被暴露。flattenActions 而不是直接展开类实例。每周安装量
188
代码仓库
GitHub 星标数
74.2K
首次出现
2026年1月24日
安全审计
已安装于
claude-code172
opencode161
gemini-cli151
codex149
cursor149
antigravity148
Main interfaces for UI components:
createTopic, sendMessage)internal_*)Core business logic implementation:
internal_ prefix (internal_createTopic)internal_dispatch*)State update handlers:
internal_dispatch + entity (internal_dispatchTopic)setUse Reducer Pattern:
messagesMap, topicMaps)Use Simpleset:
internal_createTopic: async (params) => {
const tmpId = Date.now().toString();
// 1. Immediately update frontend (optimistic)
get().internal_dispatchTopic(
{ type: 'addTopic', value: { ...params, id: tmpId } },
'internal_createTopic'
);
// 2. Call backend service
const topicId = await topicService.createTopic(params);
// 3. Refresh for consistency
await get().refreshTopic();
return topicId;
},
Delete operations : Don't use optimistic updates (destructive, complex recovery)
Actions:
createTopic, sendMessageinternal_createTopic, internal_updateMessageContentinternal_dispatchTopicinternal_toggleMessageLoadingState:
messageLoadingIds, topicEditingIdstopicMaps, messagesMapactiveTopicIdtopicsInitreferences/action-patterns.mdreferences/slice-organization.mdWe are migrating slices from plain StateCreator objects to class-based actions.
Define a class that encapsulates actions and receives (set, get, api) in the constructor.
Use #private fields (e.g., #set, #get) to avoid leaking internals.
Prefer shared typing helpers:
StoreSetter<T> from @/store/types for set.Pick<ActionImpl, keyof ActionImpl> to expose only public methods.Export a create*Slice helper that returns a class instance.
In store files, merge class instances with flattenActions (do not spread class instances).
flattenActions binds methods to the original class instance and supports prototype methods and class fields.
const createStore: StateCreator<HomeStore, [['zustand/devtools', never]]> = (...params) => ({ ...initialState, ...flattenActions<HomeStoreAction>([ createRecentSlice(...params), createHomeInputSlice(...params), ]), });
For large slices that need multiple action classes, compose them in the slice entry using flattenActions.
Use a local PublicActions<T> helper if you need to combine multiple classes and hide private fields.
type PublicActions<T> = { [K in keyof T]: T[K] };
export type ChatGroupAction = PublicActions< ChatGroupInternalAction & ChatGroupLifecycleAction & ChatGroupMemberAction & ChatGroupCurdAction
;
export const chatGroupAction: StateCreator< ChatGroupStore, [['zustand/devtools', never]], [], ChatGroupAction
= (...params) => flattenActions<ChatGroupAction>([ new ChatGroupInternalAction(...params), new ChatGroupLifecycleAction(...params), new ChatGroupMemberAction(...params), new ChatGroupCurdAction(...params), ]);
ChatGroupStoreWithSwitchTopic for lifecycle switchTopicChatGroupStoreWithRefresh for member refreshChatGroupStoreWithInternal for curd internal_dispatchChatGroupStateCreator params (set, get, api).#private to avoid set/get being exposed.flattenActions instead of spreading class instances.Weekly Installs
188
Repository
GitHub Stars
74.2K
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code172
opencode161
gemini-cli151
codex149
cursor149
antigravity148
Vite Flare Starter:开箱即用的全栈Cloudflare应用模板,集成React 19、Hono、D1
479 周安装
type Setter = StoreSetter<HomeStore>; export const createRecentSlice = (set: Setter, get: () => HomeStore, _api?: unknown) => new RecentActionImpl(set, get, _api);
export class RecentActionImpl { readonly #get: () => HomeStore; readonly #set: Setter;
constructor(set: Setter, get: () => HomeStore, _api?: unknown) { void _api; this.#set = set; this.#get = get; }
useFetchRecentTopics = () => { // ... }; }
export type RecentAction = Pick<RecentActionImpl, keyof RecentActionImpl>;