V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bthulu
V2EX  ›  React

useReducer 这个东西到底有啥用, 简单的东西搞复杂化是为了啥?

  •  1
     
  •   bthulu · 2023-10-22 10:17:25 +08:00 · 2580 次点击
    这是一个创建于 432 天前的主题,其中的信息可能已经有所发展或是发生改变。

    明明可以每个 action 对应一个函数, ide 里点下 click 的函数名, 立即跳到函数实现, 简单直观. 偏要搞个 reducer, 想看下函数实现, 得先跳到函数, 记下 dispatch 的 type, 再跳到 dispatch, 再跳到 reducer, 再在 reducer 里找 type, 这才算找到函数实现. 严重影响调试速度.

    按官方的说法, 这样做有以下几个好处:

    1. 让所有逻辑都可以存放在一个地方
    2. 有利于代码的调试
    3. 有利于代码的测试

    关于 1, 我将 action 对应的函数都写在一块, 跟用一个函数包起来放在一块, 不都是在一块吗, 有什么区别? 难道是为了避免有人破坏这个默契, 非要将处理函数东放一个西放一个?

    关于 2, 这哪里利于调试了, 简直是调试的噩梦

    关于 3, 确实纯函数方便测试, 这个不可否认. 虽然我从来没写过 reducer 的测试代码.

    19 条回复    2023-10-23 10:38:52 +08:00
    codehz
        1
    codehz  
       2023-10-22 10:28:43 +08:00
    确实 reducer 不是最优的,但这主要是取决于 js 本身的限制,但相比于 state 和一大堆 callback 乱改 state 还是有一定好处的,至少你能从 useReducer 那里看到 state 有可能的变化方式(当然你也可以摆烂只做 setState 一样的事情,那种就不提了),比如限定 state 只能+1 或者-1 ,如果用 setState ,这个意思是无法表达出来的
    不过你这把所有 click 函数都直接 dispatch 的情况,多半还是存在一些问题,相当于另一个方向摆烂,我建议可以放点代码例子来看看是不是这个方向的写法
    某种意义上说可以理解为写了一个状态机,reducer 函数就是状态转移方程,dispatch 则是触发状态转移的 trigger
    hervey0424
        2
    hervey0424  
       2023-10-22 10:46:44 +08:00
    这玩意除了给自己添堵真没啥用, 用起来麻烦, 找起来麻烦
    easychen
        3
    easychen  
       2023-10-22 11:16:41 +08:00
    这个本来就是可选的啊,场景简单的话直接上 mobx 之类就可以了吧。
    paradox8599
        4
    paradox8599  
       2023-10-22 11:38:23 +08:00 via Android
    https://github.com/pmndrs/zustand
    最近在用这个,感觉更舒服一点
    chaxus
        5
    chaxus  
       2023-10-22 12:08:04 +08:00   ❤️ 1
    reducers 是描述 action 如何改变 state 。思想是 Facebook 研究的一种 Flux 架构,用途是管理数据流,Flux 数据流周期就是这个样子:

    Views ---> (actions) ----> Dispatcher ---> (registered callback) ---> Stores -------+
    Ʌ |
    | V
    +-- (Controller-Views "change" event handlers) ---- (Stores emit "change" events) --+

    先有了思想,再实现的代码,于是 reducers 就实现成了这个复杂的样子。但从某些实际场景来说,比如 op 说的 click 的情况,action 直接对应函数不是更方便吗?这种场景确实更方便,毕竟 Flux 架构环节还是挺多的挺复杂的。
    这就是它这么复杂的原因。
    至于要不要去用它,得看实际业务情况。
    开卷有益。
    尽信书不如无书。
    kyuuseiryuu
        6
    kyuuseiryuu  
       2023-10-22 13:23:56 +08:00 via iPhone
    当一个状态是从其他很多状态合并计算过来的时候,用 useReducer 批量更新,减少 rerender 次数
    mxT52CRuqR6o5
        7
    mxT52CRuqR6o5  
       2023-10-22 13:47:58 +08:00 via Android
    这玩意儿利于调试是要配合 devtools 用的
    Leviathann
        8
    Leviathann  
       2023-10-22 13:50:31 +08:00   ❤️ 1
    解决了要传十几个不同的 callback 要给子组件写十几个参数的问题
    charlie21
        9
    charlie21  
       2023-10-22 14:54:58 +08:00 via Android
    dispatcher 是一个独立于视图层的层,在这处理好之后,再把计算结果传递给视图层。这样一来,视图层会更薄(更不携带计算量)了,只负责 event handler 和渲染数据

    层本身就是答案。至于 “为什么要切出额外一层” 那么一个人只能告诉你 这可以对他而言降低心智负担,对他而言也的确如此。但对你而言未必,你不就觉得是多此一举吗?如果你没觉得它在 “降低心智负担” 那么等你遇到了就知道了

    所有的答案都是为了特定的问题应运而生的,理解答案是无助于理解答案的,理解问题是有助于理解答案的。
    bthulu
        10
    bthulu  
    OP
       2023-10-22 16:24:10 +08:00
    @Leviathann 这个你可以定义一个 object obj = {}, 把这些参数都挂载到这个 obj 上, 然后给子组件只传这个 obj 就行了
    bthulu
        11
    bthulu  
    OP
       2023-10-22 16:26:23 +08:00
    @charlie21 但是我把所有与视图无关的函数都抽到一个.js 文件里, 一样能达到你这样的效果, 还不用绕这么多弯弯.
    我只能归结为外国人的思维跟中国人就是不一样. 就跟邮件地址一样, 我们觉得从大范围到小范围很快就能锁定具体位置, 老美偏要反过来.
    XCFOX
        12
    XCFOX  
       2023-10-22 16:31:03 +08:00
    你说的对,在 2023 年 useReducer 和 Redux 可以说是最落后的状态管理方案了。

    现在有好的多的状态管理解决方案:
    喜欢 Redux 这种单向数据流思维的可以用: https://github.com/pmndrs/zustand
    喜欢 React Hook 函数式思维的可以用: https://github.com/pmndrs/jotai
    喜欢 vue3 reactive 的可以用: https://github.com/pmndrs/valtio

    早期 React 状态管理大家都是摸着石头过河,难免会走出 useReducer 和 Redux 的弯路。
    jsq2627
        13
    jsq2627  
       2023-10-22 18:36:48 +08:00 via iPhone
    我很不解为什么要把 useReducer 做到 react core 里面
    chanChristin
        14
    chanChristin  
       2023-10-22 23:08:35 +08:00
    歪个楼,我想知道 webstorm 里面如何点击跳转到 dispatch 对应的 effects 里面。我们用的是 dva + umi ,dispatch 里面是 "module/effects",是个字符串,webstorm 无法识别。
    leokun
        15
    leokun  
       2023-10-23 08:59:18 +08:00
    useReducer 也可以做到类型安全,不过要在 typescript 上花一些功夫,当然这种花拳绣腿大家肯定看不上,不如试原子化的状态库,例如 https://jotai.org/https://github.com/pmndrs/zustand
    NessajCN
        16
    NessajCN  
       2023-10-23 09:00:26 +08:00
    就是 state 太多的时候给你合并用的
    realJamespond
        17
    realJamespond  
       2023-10-23 09:45:16 +08:00
    传参时巨有用,当接口有 10 个参数时你不可能写 10 个 state 吧
    yimity
        18
    yimity  
       2023-10-23 10:17:28 +08:00
    这个还是很有用的,多个状态交织起来的时候,很清晰很好用: https://yimity.com/2023/10/23/usereducer.html
    7inFen
        19
    7inFen  
       2023-10-23 10:38:52 +08:00
    因为 redux 出的早又深入人心,hook 出来后为降低使用负担,兼容了 redux 的思路。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2764 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:32 · PVG 22:32 · LAX 06:32 · JFK 09:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.