React 缺失的"M"层:我开发了 Zenith,把完整的 Model 带回了前端

React 缺失的"M"层:我开发了 Zenith,重塑完整的 Model

迷失的 Model

我们在谈论 React 时常说 UI = f(State)。React 完美地解决了 View(视图) 层,但对于 Model(数据模型) 层,社区的探索从未停止。

从 Redux 到 Hooks,再到 Zustand,我们越来越追求"原子化"和"碎片化"。这带来了极简的 API,但也带来了一个严重的副作用:Model(模型)的破碎

你是否遇到过这种情况:

  • 数据 (State) 定义在一个 create 函数里。
  • 计算 (Computed) 散落在组件的 useMemo 或各种 Selector 函数里。
  • 行为 (Action) 散落在 useEffect 或各个 Event Handler 里。

"Model" 消失了,取而代之的是散落在各处的逻辑碎片。

Zenith:重塑 Model 层

Zenith 注重于高内聚(Co-location) 的开发体验,可以把数据 (State)计算 (Computed)行为 (Action) 紧紧地封装在一起。

Zenith = Zustand 的极简 + MobX 的组织力 + Immer 的不可变基石

核心特性:"诚实"的 Model

1. 完整的模型定义 (Co-location)

在 Zenith 中,你不需要在闭包里用 get() 去"偷窥"状态,也不用担心 set 的黑盒逻辑。一个 Store 就是一个完整的、逻辑自洽的业务单元。

typescript 复制代码
class TodoStore extends ZenithStore<State> {
  // 1. 数据 (State)
  constructor() {
    super({ todos: [], filter: 'all' });
  }
​
  // 2. 自动计算属性 (Computed)
  // 告别手动写 Selector,告别 useMemo
  // 像定义原生 getter 一样定义派生状态
  @memo((s) => [s.state.todos, s.state.filter])
  get filteredTodos() {
    const { todos, filter } = this.state;
    // ...逻辑
  }
​
  // 3. 行为 (Action)
  // 诚实地使用 this,UI 层绝不能直接碰 State
  addTodo(text: string) {
    this.produce((draft) => {
      draft.todos.push({ text, completed: false });
    });
  }
}

2. 链式派生:自动化的数据流

MobX 最让人着迷的是它的自动响应能力。Zenith 完美复刻了这一点,但底层依然是 Immutable Data

你可以基于一个计算属性,派生出另一个计算属性(A -> B -> C)。当 A 变化时,C 会自动更新。我们不再需要手动维护依赖链,也不需要在组件里写一堆 useMemo一切计算逻辑都收敛在 Model 内部

3. 组件即视图 (View):像 Zustand 一样简单

定义 Model 虽然严谨,但在组件里使用必须极致简单。Zenith 提供了完全符合 React Hooks 习惯的 API。

你不需要高阶组件(HOC),不需要 Connect,只需要一个 Hook:

javascript 复制代码
const { useStore, useStoreApi } = createReactStore(TodoStore);
​
function TodoList() {
  // ✅ 像 Zustand 一样选择状态
  // 只有当 filteredTodos 变化时,组件才会重渲染
  const todos = useStore((s) => s.filteredTodos);
  
  // ✅ 获取完整的 Model 实例 (Action)
  const store = useStoreApi();
​
  return (
    <div>
      {todos.map((todo) => (
         // UI 只负责触发意图,不负责实现逻辑
        <div onClick={() => store.toggle(todo.id)}>
          {todo.text}
        </div>
      ))}
    </div>
  );
}

4. 工程化的胜利

Zenith 不仅仅是一个状态库,它内置了 History (撤销/重做)DevTools 中间件。

我用它构建了 domd markdown WYSIWYG 编辑器,能够支撑 20000行文档流畅编辑。

结语

Zenith 的出现不是为了争论 FP 好还是 OOP 好。

它只是想告诉你:当你的项目逻辑日益复杂,当你受够了在几十个 Hook 文件中跳来跳去寻找业务逻辑时,你值得拥有一个完整的、诚实的 Model 层。

让代码重归秩序。

Github: github.com/do-md/zenit...

欢迎 Star 🌟 和 Issue 交流!

相关推荐
摘星编程7 小时前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
jin1233229 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos
jin12332210 小时前
基于React Native鸿蒙跨平台移动端表单类 CRUD 应用,涵盖地址列表展示、新增/编辑/删除/设为默认等核心操作
react native·react.js·ecmascript·harmonyos
徐同保11 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js
浮游本尊11 小时前
React 18.x 学习计划 - 第十三天:部署与DevOps实践
学习·react.js·状态模式
摘星编程12 小时前
OpenHarmony环境下React Native:DatePicker日期选择器
react native·react.js·harmonyos
橙露12 小时前
NNG通信框架:现代分布式系统的通信解决方案与应用场景深度分析
运维·网络·tcp/ip·react.js·架构
摘星编程12 小时前
用React Native开发OpenHarmony应用:Calendar日期范围选择
javascript·react native·react.js
摘星编程16 小时前
React Native鸿蒙:Tree节点选择状态
react native·react.js·harmonyos
摘星编程16 小时前
用React Native开发OpenHarmony应用:StickyHeader粘性标题
javascript·react native·react.js