Redux - 纯函数


函数是一个过程,它接受称为参数的输入,并产生称为返回值的输出。如果函数遵循以下规则,则称为纯函数 -

  • 函数对于相同的参数返回相同的结果。

  • 它的评估没有副作用,即它不会改变输入数据。

  • 局部和全局变量没有突变。

  • 它不像全局变量那样依赖于外部状态。

让我们以一个函数为例,该函数返回作为函数输入传递的值的两倍。一般来说,可以写为:f(x) => x*2。如果使用参数值 2 调用函数,则输出将为 4,f(2) => 4。

让我们用 JavaScript 编写函数的定义,如下所示 -

const double = x => x*2; // es6 arrow function
console.log(double(2));  // 4

这里,double是一个纯函数。

根据Redux中的三原则,更改必须由纯函数(即Redux中的reducer)进行。现在,出现了一个问题:为什么减速器必须是纯函数。

假设您想要调度一个类型为“ADD_TO_CART_SUCCESS”的操作,通过单击“添加到购物车”按钮将商品添加到您的购物车应用程序。

让我们假设减速器正在向您的购物车添加一个项目,如下所示 -

const initialState = {
   isAddedToCart: false;
}
const addToCartReducer = (state = initialState, action) => { //es6 arrow function
   switch (action.type) {
      case 'ADD_TO_CART_SUCCESS' :
         state.isAddedToCart = !state.isAddedToCart; //original object altered
         return state;
      default:
         return state;
   }
}
export default addToCartReducer ;

让我们假设,isAddedToCart是状态对象的一个​​属性,它允许您通过返回布尔值 ' true 或 false'来决定何时禁用该项目的“添加到购物车”按钮。这可以防止用户多次添加相同的产品。现在,我们不再返回新对象,而是像上面那样在状态上改变 isAddedToCart 属性。现在,如果我们尝试将商品添加到购物车,则不会发生任何事情。添加到购物车按钮不会被禁用。

这种Behave的原因如下 -

Redux 通过新旧对象的内存位置来比较这两个对象。如果发生任何变化,它期望来自减速器的新对象。如果没有发生变化,它还期望取回旧对象。在这种情况下,也是一样的。由于这个原因,Redux 假设什么都没有发生。

所以,Redux中的reducer必须是纯函数。以下是一种无需突变的编写方法 -

const initialState = {
   isAddedToCart: false;
}
const addToCartReducer = (state = initialState, action) => { //es6 arrow function
   switch (action.type) {
      case 'ADD_TO_CART_SUCCESS' :
         return {
            ...state,
            isAddedToCart: !state.isAddedToCart
         }
      default:
         return state;
   }
}
export default addToCartReducer;