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)进行。现在,问题出现了,为什么 reducer 必须是纯函数?

假设您想分派一个类型为 'ADD_TO_CART_SUCCESS' 的 action,通过单击“添加到购物车”按钮将商品添加到您的购物车应用程序中。

让我们假设 reducer 正在将商品添加到您的购物车,如下所示:

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 是 state 对象上的一个属性,它允许您通过返回布尔值 “true 或 false” 来决定何时禁用商品的“添加到购物车”按钮。这可以防止用户多次添加同一产品。现在,我们不是返回一个新对象,而是像上面那样修改 state 上的 isAddedToCart 属性。现在,如果我们尝试将商品添加到购物车,则不会发生任何事情。“添加到购物车”按钮不会被禁用。

这种行为的原因如下:

Redux 通过比较两个对象的内存位置来比较旧对象和新对象。如果发生任何更改,它期望 reducer 返回一个新对象。并且如果没有任何更改,它也期望获得旧对象。在这种情况下,它是一样的。由于这个原因,Redux 假设什么也没有发生。

因此,reducer 在 Redux 中必须是纯函数是必要的。以下是在不进行修改的情况下编写它的方法:

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;
广告