SampsonKY / Daily_question

KY 的每日一题
3 stars 1 forks source link

为什么 reducer 是一个纯函数 #2

Open SampsonKY opened 4 years ago

SampsonKY commented 4 years ago

纯函数是什么

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

可观察的副作用

例子

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

用处

redux 中的 reducer

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

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

reducer的几种写法

  1. 直接返回一个对象

    case 'TOGGLE':
    return {
           ...state,
           completed: !state.completed
       }
  2. 使用 Object.assign()返回一个对象

    case 'TOGGLE':
    return Object.assign({},state,completed: !state.completed)
  3. 使用 Immutable.js 返回一个新对象

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

为什么 reducer 必须是纯函数

image-20200927211945240

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

为什么这么设计

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

参考

纯函数以及为什么要用纯函数

Reducer 为什么必须是纯函数?