明明可以每个 action 对应一个函数, ide 里点下 click 的函数名, 立即跳到函数实现, 简单直观. 偏要搞个 reducer, 想看下函数实现, 得先跳到函数, 记下 dispatch 的 type, 再跳到 dispatch, 再跳到 reducer, 再在 reducer 里找 type, 这才算找到函数实现. 严重影响调试速度.
按官方的说法, 这样做有以下几个好处:
关于 1, 我将 action 对应的函数都写在一块, 跟用一个函数包起来放在一块, 不都是在一块吗, 有什么区别? 难道是为了避免有人破坏这个默契, 非要将处理函数东放一个西放一个?
关于 2, 这哪里利于调试了, 简直是调试的噩梦
关于 3, 确实纯函数方便测试, 这个不可否认. 虽然我从来没写过 reducer 的测试代码.
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 |
2
hervey0424 2023-10-22 10:46:44 +08:00
这玩意除了给自己添堵真没啥用, 用起来麻烦, 找起来麻烦
|
3
easychen 2023-10-22 11:16:41 +08:00
这个本来就是可选的啊,场景简单的话直接上 mobx 之类就可以了吧。
|
4
paradox8599 2023-10-22 11:38:23 +08:00 via Android
https://github.com/pmndrs/zustand
最近在用这个,感觉更舒服一点 |
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 架构环节还是挺多的挺复杂的。 这就是它这么复杂的原因。 至于要不要去用它,得看实际业务情况。 开卷有益。 尽信书不如无书。 |
6
kyuuseiryuu 2023-10-22 13:23:56 +08:00 via iPhone
当一个状态是从其他很多状态合并计算过来的时候,用 useReducer 批量更新,减少 rerender 次数
|
7
mxT52CRuqR6o5 2023-10-22 13:47:58 +08:00 via Android
这玩意儿利于调试是要配合 devtools 用的
|
8
Leviathann 2023-10-22 13:50:31 +08:00 1
解决了要传十几个不同的 callback 要给子组件写十几个参数的问题
|
9
charlie21 2023-10-22 14:54:58 +08:00 via Android
dispatcher 是一个独立于视图层的层,在这处理好之后,再把计算结果传递给视图层。这样一来,视图层会更薄(更不携带计算量)了,只负责 event handler 和渲染数据
层本身就是答案。至于 “为什么要切出额外一层” 那么一个人只能告诉你 这可以对他而言降低心智负担,对他而言也的确如此。但对你而言未必,你不就觉得是多此一举吗?如果你没觉得它在 “降低心智负担” 那么等你遇到了就知道了 所有的答案都是为了特定的问题应运而生的,理解答案是无助于理解答案的,理解问题是有助于理解答案的。 |
10
bthulu OP @Leviathann 这个你可以定义一个 object obj = {}, 把这些参数都挂载到这个 obj 上, 然后给子组件只传这个 obj 就行了
|
11
bthulu OP @charlie21 但是我把所有与视图无关的函数都抽到一个.js 文件里, 一样能达到你这样的效果, 还不用绕这么多弯弯.
我只能归结为外国人的思维跟中国人就是不一样. 就跟邮件地址一样, 我们觉得从大范围到小范围很快就能锁定具体位置, 老美偏要反过来. |
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 的弯路。 |
13
jsq2627 2023-10-22 18:36:48 +08:00 via iPhone
我很不解为什么要把 useReducer 做到 react core 里面
|
14
chanChristin 2023-10-22 23:08:35 +08:00
歪个楼,我想知道 webstorm 里面如何点击跳转到 dispatch 对应的 effects 里面。我们用的是 dva + umi ,dispatch 里面是 "module/effects",是个字符串,webstorm 无法识别。
|
15
leokun 2023-10-23 08:59:18 +08:00
useReducer 也可以做到类型安全,不过要在 typescript 上花一些功夫,当然这种花拳绣腿大家肯定看不上,不如试原子化的状态库,例如 https://jotai.org/ ,https://github.com/pmndrs/zustand
|
16
NessajCN 2023-10-23 09:00:26 +08:00
就是 state 太多的时候给你合并用的
|
17
realJamespond 2023-10-23 09:45:16 +08:00
传参时巨有用,当接口有 10 个参数时你不可能写 10 个 state 吧
|
18
yimity 2023-10-23 10:17:28 +08:00
这个还是很有用的,多个状态交织起来的时候,很清晰很好用: https://yimity.com/2023/10/23/usereducer.html
|
19
7inFen 2023-10-23 10:38:52 +08:00
因为 redux 出的早又深入人心,hook 出来后为降低使用负担,兼容了 redux 的思路。
|