npx skills add https://github.com/lobehub/lobehub --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 而不是直接展开类实例。每周安装量
763
代码仓库
GitHub 星标数
74.3K
首次出现
2026 年 1 月 27 日
安全审计
已安装于
opencode675
codex668
gemini-cli658
github-copilot639
kimi-cli582
amp580
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
763
Repository
GitHub Stars
74.3K
First Seen
Jan 27, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode675
codex668
gemini-cli658
github-copilot639
kimi-cli582
amp580
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
103,800 周安装
Refactoring UI 设计系统:实用 UI 设计原则与前端代码优化指南
723 周安装
Refero-design:研究优先设计方法 - 从最佳实践学习,打造独特产品界面
724 周安装
日历自动化:Google Calendar与Outlook会议管理、时间块划分、每日摘要同步工作流
725 周安装
高级运维开发工程师工具包:自动化脚本、CI/CD流水线、Terraform脚手架、部署管理
726 周安装
Claude 代码插件技能开发指南 - 创建模块化AI技能扩展Claude能力
726 周安装
GitHub工作流自动化技能:AI辅助PR审查、问题分类与CI/CD集成
727 周安装
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>;