【问题标题】:Redux-persist react native AsyncStorage Object Serialization Objects Not EqualRedux-persist react native AsyncStorage Object Serialization Objects Not Equal
【发布时间】:2017-01-09 08:56:01
【问题描述】:

我正在使用 redux persist 自动持久化应用程序启动时的状态,如文档中所述,特别是使用 AsyncStorage:https://github.com/rt2zz/redux-persist

我在下面定义了一个减速器,它将当前产品添加到 state.products 中的购物车中

case 'ADD_PRODUCT':
  let addedProducts = [...state.products]
  addedProducts.push(action.product);
  return {
    ...state,
    count: ++state.count,
    products: addedProducts
  };

case 'REMOVE_PRODUCT':
  let count = state.count;
  let removedProducts = [...state.products];
  let idxOfProduct = state.products.indexOf(action.product);
  if(idxOfProduct != -1){
    count = --state.count;
    removedProducts.splice(idxOfProduct,1);
  }

return{
    ...state,
    count: count,
    products: removedProducts
    }; 

#1。如果我发送“ADD_PRODUCT”,它会添加产品,然后如果我发送“REMOVE_PRODUCT”,它会按预期删除该项目。

#2.1 如果我调度 ADD_PRODUCT 然后重新加载我的应用程序,state.products 会按预期重新水化并包含最近添加的产品。

#2.1. 但是,在我重新加载应用程序后,尝试调用 REMOVE_PRODUCT(与我在上面 #1 中调用 REMOVE_PRODUCT 的方式完全相同)。即使 state.products 包含产品 state.products.indexOf(action.product); 返回 -1,因此它不会被删除。

为什么在调用 REMOVE_PRODUCT 时,#1 中的 IndexOf 方法可以正常工作。但是,如果我添加一个产品(ADD_PRODUCT)然后重新加载我的应用程序并调用 REMOVE_PRODUCT,IndexOf 会返回 -1,即使它存在于 state.products 中

【问题讨论】:

    标签: javascript reactjs react-native redux react-redux


    【解决方案1】:

    我认为问题可能与 indexOf 对待对象相等的方式有关。

    无需重新加载,您将添加和删除相同的对象引用,这没关系。

    重新加载时,state.products 中加载的引用与action.product 中加载的引用不同,因此 indexOf 找不到它并且永远不会返回索引。

    要解决此问题,我将使用产品 ID 在 state.products 数组中查找该产品,而不是尝试查找整个对象。

    为了说明我的答案,这就是你正在做的事情:

    var a = {obj: 0};
    var b = [a];
    b.indexOf({obj: 0}); // -1 not found
    

    这是你应该做的:

    var a = {id: '26833', obj: 0};
    var b = [a];
    b.findIndex(function(el){ //findIndex is not supported in IE, find a polyfill for it
       return el.id === '26833'
    }); //0
    

    【讨论】:

      【解决方案2】:

      发生这种情况是因为 indexOf 使用 strict reference equality 检查来查找数组中的元素。这意味着对象具有相同的字段和值是不够的:它必须是相同的对象。重新加载应用程序后,这永远不会是真的,因为原始对象已被销毁。

      如果您的产品有某种唯一 ID 字段,最简单的方法是过滤列表以排除具有匹配 ID 的项目:

      const products = state.products.filter(p => p.id !== action.product.id);
      const count = products.length;
      
      return { ...state, products, count };
      

      【讨论】:

        猜你喜欢
        • 2021-08-30
        • 2018-05-23
        • 1970-01-01
        • 2019-10-22
        • 1970-01-01
        • 1970-01-01
        • 2020-03-31
        • 2017-04-30
        • 1970-01-01
        相关资源
        最近更新 更多