为什么 reducer 是一个纯函数

发布于 2021-01-25 14:09:26 字数 2656 浏览 1396 评论 0

纯函数是什么

纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。

可观察的副作用

  • 进行一个 HTTP 请求
  • Mutating data
  • 输出数据到屏幕或者控制台
  • DOM 查询/操作
  • Math.random()
  • 获取的当前时间

例子

function priceAfterTax(productPrice) { return (productPrice * 0.20) + productPrice;}

用处

  • 纯函数在函数式编程中广泛应用
  • 便于测试,如果传入相同的参数,将始终产生相同的结果
  • 使得维护和重构代码变得更加容易。你可以放心地重构一个纯函数,不必操心没注意到的副作用搞乱了整个应用而导致终调试地狱。

redux 中的 reducer

reducer 就是一个纯函数,接受旧的 state 和 action,返回新的 state

redux 可以提供可预测化的状态管理。在一个应用中,所有的 state 都是以一个对象树的形式存在在一个单一的 store 中,唯一改变 state 的方法就是触发 action,而 reducer 就是用来编写专门的函数决定每个 action 如何改变应用的 state。

reducer 的几种写法

直接返回一个对象

case 'TOGGLE':
	return {
        ...state,
        completed: !state.completed
    }

使用 Object.assign() 返回一个对象

case 'TOGGLE':
	return Object.assign({},state,completed: !state.completed)

使用 Immutable.js 返回一个新对象

case 'TOGGLE':
	return state.updateIn(['completed'], ()=>!state.getIn('completed'))

为什么 reducer 必须是纯函数

  • 修改传入的参数。如果直接修改 state的话,那么在reducer修改的那个时间内,redux里面依赖的历史数据的功能就没办法实现了。而且如果改变传入的state或state里面的key值,那么在react之前就应用了该state,它是无法判断该state是否有变化,从而不会更新。
  • 不能调用非纯函数。如果调用非纯函数的话,相同的 action 可能导致不同的结果,这样 reducer 的处理过程是不可预料的。
  • 不能执行有副作用的操作,涉及到后台,同样的 action 可能会出现不同的结果,会导致不可预料。其次是 API 的调用,因为 API 要请求一个异步函数,想让这个异步函数的返回结果应用到 state 上,但由于 reducer 新的 state(同步)是在异步请求完成之前返回的,所以异步函数无法影响到新的 state
  • redux 源码:

通过源代码,我们发现,var nextStateForKey = reducer(previousStateForKey, action), nextStateForKey 就是通过 reducer 执行后返回的结果 (state),然后通过hasChanged = hasChanged || nextStateForKey !== previousStateForKey来比较新旧两个对象是否一致,此比较法,比较的是两个对象的存储位置,也就是浅比较法,所以,当我们 reducer 直接返回旧的 state 对象时,Redux 认为没有任何改变,从而导致页面没有更新。

为什么这么设计

因为比较两个 javascript 对象中所有的属性是否完全相同,唯一的办法就是深比较,然而,深比较在真实的应用中代码是非常大的,非常耗性能的,需要比较的次数特别多,所以一个有效的解决方案就是做一个规定,当无论发生任何变化时,开发者都要返回一个新的对象,没有变化时,开发者返回就的对象,这也就是 redux 为什么要把 reducer 设计成纯函数的原因。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

6118422078

文章 0 评论 0

Bonjour°[大白

文章 0 评论 0

別甾虛僞

文章 0 评论 0

qq_FynBW0

文章 0 评论 0

浅笑依然

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文