Redux持久反应本机异步存储对象序列化对象不相等



我使用redux persistent在应用程序启动时自动保持和重新水合状态,如文档中所述,特别是使用AsyncStorage:https://github.com/rt2zz/redux-persist.

我在下面定义了一个reducer,它将当前添加到购物车中的产品保持在状态。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,即使它存在于状态中。products

我认为这个问题可能与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
发生这种情况的原因是indexOf使用严格的引用相等性检查来查找数组中的元素。这意味着仅仅让对象具有相同的字段和值是不够的:它需要是完全相同的对象。在重新加载应用程序后,这永远不可能是真的,因为原始对象已经被销毁。

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

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

相关内容

  • 没有找到相关文章

最新更新