前言
本文不讲 react、redux、action、reducer 的具体应用,只是单纯的讲解 reducer 为什么必须是纯函数,本文适合有一定 redux 开发经验的同学。
用过 react 的同学对 redux 一定不会陌生,我们知道 redux 可以提供可预测化的状态管理。在一个应用中,所有的 state 都是以一个对象树的形式存在一个单一的 store 中,唯一改变 state 的办法就是触发 action,而 reducer 就是用来编写专门的函数决定每个 action 如何改变应用的 state 。
如官网所说,reducer 就是一个纯函数,接受旧的 state 和 action,返回新的 state (previousState, action) => newState
我们的疑问来了:
为什么reducer 必须是一个纯函数?
为什么必须返回一个新的 state?
返回旧的 state 为什么不行?
redux 源码是怎么写的?
纯函数写法
我们首先来看下正常案例,我们一般会有如下几种写法返回新state:
- 直接返回一个新对象
- 使用 Object.assign()返回一个新对象
- 使用 Immutable.js 返回一个新对象
在 Redux store 中保存了 reducer 返回的 这个 state,这个新的 store 树就是应用的下一个 state, 所有订阅 store.subscribe(listener)
的监听器都将被调用,监听器里可以调用 store.getState()
获得当前 state 此时,我们就可以使用新的 state 来更新 UI setState(newState)
什么是纯函数?
这里简单的讲解一下什么是纯函数?
- 相同的输入永远返回相同的输出
- 不修改函数的输入值
- 不依赖外部环境状态
- 无任何副作用
为什么reducer必须为纯函数?
我们先来试验下,如果 reducer 不是纯函数会发生什么? 我们将上面代码reducer改造一下,直接修改 state,而不是返回新的 state
改变代码后,我们发现当我们触发了 action 以后,页面没有发生任何变化,这是为什么呢?
我们来看下 redux 源码:
通过源代码,我们发现,var nextStateForKey = reducer(previousStateForKey, action)
, nextStateForKey就是通过 reducer 执行后返回的结果(state),然后通过hasChanged = hasChanged || nextStateForKey !== previousStateForKey
来比较新旧两个对象是否一致,此比较法,比较的是两个对象的存储位置,也就是浅比较法,所以,当我们 reducer 直接返回旧的 state 对象时,Redux 认为没有任何改变,从而导致页面没有更新。
为什么 Redux 会这样设计?
因为比较两个 javascript 对象中所有的属性是否完全相同,唯一的办法就是深比较,然而,深比较在真实的应用中代码是非常大的,非常耗性能的,需要比较的次数特别多,所以一个有效的解决方案就是做一个规定,当无论发生任何变化时,开发者都要返回一个新的对象,没有变化时,开发者返回就的对象,这也就是 redux 为什么要把 reducer 设计成纯函数的原因。
转载于:https://juejin.im/post/5c0398d3e51d453f32195571
今天的文章Reducer 为什么必须是纯函数?分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/28030.html