V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
jaydenWang
V2EX  ›  程序员

不够“坦诚”的 Zustand:我们是否为了函数式而函数式?

  •  
  •   jaydenWang · 1 小时 59 分钟前 · 307 次点击

    引言

    Zustand 是目前 React 生态中最流行的状态管理库之一。它以极简著称,也是我个人非常喜欢的库。 但在长期的使用中,我常常产生一种违和感:我们在一个名为“函数式”的库里,费力地模拟着面向对象。

    那个无处不在的 get()

    来看看经典的 Zustand 写法:

    const useStore = create((set, get) => ({
      count: 0,
      inc: () => set({ count: get().count + 1 }),
      actionB: () => {
        // 调用另一个 Action
        get().inc(); 
        // 获取当前状态
        const val = get().count;
      }
    }))
    

    仔细审视这个 get()

    1. **它就是 this**:它的作用就是访问当前实例的上下文。
    2. 它是“二等公民” :你必须显式地调用它 get(),而且它打破了 JS 引擎对 this 的自然优化。
    3. 心智负担:在写复杂逻辑时,你满屏都是 get().xxx,这并不比 this.xxx 优雅,反而增加了一层函数调用括号的视觉噪音。

    那个黑盒般的 set

    set 函数的设计初衷是好的(提供类似 setState 的原子更新),但在复杂场景下,它显得不够“坦诚”:

    1. 语义模糊set 隐藏了更新的细节。是合并?是替换?是深拷贝?你必须去查文档或看源码才能确定它是 "Auto Merging" 的。
    2. 逻辑断层:当你想复用一段逻辑(比如 Private Method )时,你发现你很难在 create 的闭包里优雅地定义私有辅助函数,往往只能写在外面,破坏了 Store 的内聚性。

    为了函数式而函数式?

    我们推崇函数式编程( FP ),是因为它有 纯函数无副作用引用透明 等数学上的美感。

    但 Zustand 的 Store 定义是纯函数吗?显然不是。它是一个包含了状态( State )和行为( Action )的容器。 在计算机科学中,状态 + 行为 = 对象( Object )

    既然我们本质上是在构建一个对象,为什么要回避 JS 语言原生提供的、经过几十年打磨的构建对象的最佳工具——Class

    我们为了避嫌 "OOP",发明了一套 (set, get) => ({...}) 的 DSL 。这不仅牺牲了 Class 的继承、属性访问器( Getter/Setter )等高级能力,还增加了一层理解成本。

    这是否是一种形式上的函数式正确,而非工程上的务实选择

    另一种可能性

    如果在 React 状态管理中,我们不再视 class 为洪水猛兽,而是承认它作为 "Model" 载体的合理性,会发生什么? 这或许值得我们深思。

    1 条回复    2025-12-23 12:06:15 +08:00
    tangdw
        1
    tangdw  
       32 分钟前
    set 支持函数式更新 set(state => result) 不必在 set 里面调 get
    action 里面最好在顶部声明 const { count } = get() ,要是异步里面的话就只能 get().count 这也是为了避免闭包拿到旧的状态
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   3539 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:39 · PVG 12:39 · LAX 20:39 · JFK 23:39
    ♥ Do have faith in what you're doing.