因此,我有两个数组,一个称为incart
,另一个名为products
incart
数组包含对象(表示他们在购物车中的项目(。每个对象由乘积id
和乘积qty
组成。
此外,products
阵列包含网站上的所有产品。例如,在products
数组中,每个项都有对象。它包含了一堆关于该产品的信息。这里最重要的是产品price
。
简而言之,我需要把所有的价格加起来。复杂的事情是将单个乘积qty
与乘积price
进行匹配,它们在两个阵列中找到。
因此,我的设置如下:products数组表示用户购物车中的所有商品,这是通过incart
数组进行过滤来设置的,这样做是为了获得每个商品的价格。
const {incart} = useContext(ContextApp)
const [products, setProducts] = useState([])
useEffect(()=> {
db.collection('products').doc('products').onSnapshot(snap=> {
const productsdata = snap.data().products
setProducts(productsdata.filter(x=> incart.some(el=> x.id === el.id)))
})
},[incart])
我想知道如何将这两个数组关联起来,也许可以将它们压缩成另一个数组,简而言之,这个数组只包含物品的价格和数量。
const incart = [{id: 1, qty: 1}, {id: 2, qty: 10}]
const products = [
{id: 1, price: 1},
{id: 2, price: 10}
]
const total = incart.reduce((acc, {id, qty}) =>
acc + qty * products.find(x => x.id === id).price, 0)
console.log(total)
您将产品列表用作查找表,因此我将使用Map而不是数组。
当购物车中的项目列表发生变化时,您也不一定需要从Firebase重新蚀刻所有产品,所以我会将产品映射存储在状态中,然后计算组件主体中的总价。
顺便说一句,onSnapshot
方法订阅文档中的更改,因此您要么需要使用get()
,要么需要在组件卸载时取消订阅。您可以通过从效果主体返回取消订阅功能来完成此操作。
function MyComponent() {
const { incart } = useContext(ContextApp);
const [products, setProducts] = useState(null);
useEffect(() => {
const unsubscribe = db.collection("products")
.doc("products")
.onSnapshot((snap) => {
const productsdata = snap.data().products;
setProducts(
new Map(productsdata.map(p => [p.id, p]))
);
});
return unsubscribe;
}, []);
const prices = products != null
? incart.map(p => products.get(p.id).price)
: [];
const totalPrice = prices.reduce((total, p) => total + p, 0);
// ...
}