每个用户保存或存储购物车项目的最佳方式? (最佳实践或方式)[MERNG STACK]
Best Way to Save or Store Cart Items by each user? (Best Practice or Way) [MERNG STACK]
我正在尝试为我的个人项目制作电子商务,并且我正在尝试使用我所学的一切来做到这一点。我目前有这段代码允许您将 cartItems
存储在本地存储中,但我认为我所做的是不正确的,因为在这种情况下,例如 user 1
将他的商品添加到购物车或将产品添加到购物车,然后 user 2
可以在我登录时访问或拥有相同的购物车跟他们。 用户保存 cartItems
的最佳做法或选择是什么?或者,更确切地说,我应该怎么做?
Currently the technology I use the
M(ongoDB)E(xpress)R(eact)N(odejs)G(raphql) and Apollo for my state management.
代码
购物车上下文:
import { createContext, useState, useContext, useEffect } from "react";
import { AuthContext } from "../auth";
export const CartContext = createContext();
export const CartProvider = ({ children }) => {
const { user } = useContext(AuthContext);
const cartFromLocalStorage =
(typeof window !== "undefined" &&
JSON.parse(localStorage.getItem("cart"))) ||
[];
const [cartItems, setCartItem] = useState(cartFromLocalStorage);
useEffect(() => {
if (typeof window !== "undefined") {
if (user) { // This just shows if the user is loggedIn
localStorage.setItem("cart", JSON.stringify(cartItems));
}
}
}, [cartItems]);
return (
<CartContext.Provider value={[cartItems, setCartItem]}>
{children}
</CartContext.Provider>
);
};
这是我的 CartContext
,在这里我可以看到用户添加到他们的购物车中的东西,并在我需要的时候随时调用它,因为它不是一个上下文需要将道具传递给组件。
商店:
import { useContext } from "react";
import { useQuery } from "@apollo/react-hooks";
import { FETCH_PRODUCTS_QUERY } from "../util/graphql/Queries";
import { Grid, Transition } from "semantic-ui-react";
import ProductCard from "../components/products/ProductCard";
import { CartContext } from "../context/cart/CartContext";
function Shop() {
const { loading, data: Products } = useQuery(FETCH_PRODUCTS_QUERY);
const { getProducts: products } = { ...Products };
const [cartItems, setCartItems] = useContext(CartContext);
const addToCart = (product) => {
const exist = cartItems.find((x) => x.id === product.id);
if (exist) {
setCartItems(
cartItems.map((x) =>
x.id == product.id ? { ...exist, quantity: exist.quantity + 1 } : x
)
);
} else {
setCartItems([...cartItems, { ...product, quantity: 1 }]);
}
};
const ProductList = products?.map((product) => (
<Grid.Column key={product.id} style={{ marginBottom: 20 }}>
<ProductCard
product={product}
addToCart={(product) => addToCart(product)}
/>
</Grid.Column>
));
return (
<>
<Grid columns={3}>
<Grid.Row className="page-title">
<h1>Recent Products</h1>
</Grid.Row>
<Grid.Row>
{loading ? (
<h1>Loading products..</h1>
) : (
<Transition.Group>{ProductList}</Transition.Group>
)}
</Grid.Row>
</Grid>
</>
);
}
export default Shop;
这是我的商店或产品所在的位置,如图所示我将 addToCart function
传递给了 ProductCard
组件。
产品卡:
import { Image, Card } from "semantic-ui-react";
import Link from "next/link";
import Rating from "../reviews/Rating";
function ProductCard({ product, addToCart }) {
const {
id,
name,
featureImage,
productCurrentPrice,
productPreviousPrice,
rating,
numReviews,
} = product;
return (
<>
<Card>
<Image
src={featureImage}
width={200}
height={200}
alt="Product Image"
className="product-image"
/>
<Card.Content>
<Card.Header>
<Link href={`/products/${id}`}>{name}</Link>
</Card.Header>
<Card.Meta>
<span className="date">
₱{productCurrentPrice.toLocaleString()}
</span>
<span className="date">
<strike>₱{productPreviousPrice.toLocaleString()}</strike>
</span>
<span className="header">{percentOff} % OFF</span>
</Card.Meta>
</Card.Content>
<Card.Content extra>
<div className="ui two buttons">
<button
className="ui basic green button"
onClick={() => addToCart(product)}
>
Add To Cart
</button>
</div>
</Card.Content>
</Card>
</>
);
}
export default ProductCard;
这是我的 ProductCard 组件,当 addToCart 时,它将像这样转到 localStorage:
如上图,cart key
的图片是我添加的所有商品都输入的地方。即使我注销时 cartItem
仍然显示在那里,它不应该。
如果您需要更多的说明或解释,我可以提供,如果我也提供代码,我将尽可能透明。
由于每个用户都有自己独特的购物车,您可以保存购物车信息以及当前用户userId/username 作为标识符。因此,当用户登录时,您可以 使用该用户的标识符
获取他们的购物车
通常对于存储此类敏感数据,最好将它们直接保存在您的数据库中而不是本地存储中。
您可以创建一个异步 Api 调用,这样每当您将商品添加到购物车时,您在 table 中的相应数据也会更新。示例“购物车”table 包含所有用户的当前购物车详细信息
我正在尝试为我的个人项目制作电子商务,并且我正在尝试使用我所学的一切来做到这一点。我目前有这段代码允许您将 cartItems
存储在本地存储中,但我认为我所做的是不正确的,因为在这种情况下,例如 user 1
将他的商品添加到购物车或将产品添加到购物车,然后 user 2
可以在我登录时访问或拥有相同的购物车跟他们。 用户保存 cartItems
的最佳做法或选择是什么?或者,更确切地说,我应该怎么做?
Currently the technology I use the M(ongoDB)E(xpress)R(eact)N(odejs)G(raphql) and Apollo for my state management.
代码
购物车上下文:
import { createContext, useState, useContext, useEffect } from "react";
import { AuthContext } from "../auth";
export const CartContext = createContext();
export const CartProvider = ({ children }) => {
const { user } = useContext(AuthContext);
const cartFromLocalStorage =
(typeof window !== "undefined" &&
JSON.parse(localStorage.getItem("cart"))) ||
[];
const [cartItems, setCartItem] = useState(cartFromLocalStorage);
useEffect(() => {
if (typeof window !== "undefined") {
if (user) { // This just shows if the user is loggedIn
localStorage.setItem("cart", JSON.stringify(cartItems));
}
}
}, [cartItems]);
return (
<CartContext.Provider value={[cartItems, setCartItem]}>
{children}
</CartContext.Provider>
);
};
这是我的 CartContext
,在这里我可以看到用户添加到他们的购物车中的东西,并在我需要的时候随时调用它,因为它不是一个上下文需要将道具传递给组件。
商店:
import { useContext } from "react";
import { useQuery } from "@apollo/react-hooks";
import { FETCH_PRODUCTS_QUERY } from "../util/graphql/Queries";
import { Grid, Transition } from "semantic-ui-react";
import ProductCard from "../components/products/ProductCard";
import { CartContext } from "../context/cart/CartContext";
function Shop() {
const { loading, data: Products } = useQuery(FETCH_PRODUCTS_QUERY);
const { getProducts: products } = { ...Products };
const [cartItems, setCartItems] = useContext(CartContext);
const addToCart = (product) => {
const exist = cartItems.find((x) => x.id === product.id);
if (exist) {
setCartItems(
cartItems.map((x) =>
x.id == product.id ? { ...exist, quantity: exist.quantity + 1 } : x
)
);
} else {
setCartItems([...cartItems, { ...product, quantity: 1 }]);
}
};
const ProductList = products?.map((product) => (
<Grid.Column key={product.id} style={{ marginBottom: 20 }}>
<ProductCard
product={product}
addToCart={(product) => addToCart(product)}
/>
</Grid.Column>
));
return (
<>
<Grid columns={3}>
<Grid.Row className="page-title">
<h1>Recent Products</h1>
</Grid.Row>
<Grid.Row>
{loading ? (
<h1>Loading products..</h1>
) : (
<Transition.Group>{ProductList}</Transition.Group>
)}
</Grid.Row>
</Grid>
</>
);
}
export default Shop;
这是我的商店或产品所在的位置,如图所示我将 addToCart function
传递给了 ProductCard
组件。
产品卡:
import { Image, Card } from "semantic-ui-react";
import Link from "next/link";
import Rating from "../reviews/Rating";
function ProductCard({ product, addToCart }) {
const {
id,
name,
featureImage,
productCurrentPrice,
productPreviousPrice,
rating,
numReviews,
} = product;
return (
<>
<Card>
<Image
src={featureImage}
width={200}
height={200}
alt="Product Image"
className="product-image"
/>
<Card.Content>
<Card.Header>
<Link href={`/products/${id}`}>{name}</Link>
</Card.Header>
<Card.Meta>
<span className="date">
₱{productCurrentPrice.toLocaleString()}
</span>
<span className="date">
<strike>₱{productPreviousPrice.toLocaleString()}</strike>
</span>
<span className="header">{percentOff} % OFF</span>
</Card.Meta>
</Card.Content>
<Card.Content extra>
<div className="ui two buttons">
<button
className="ui basic green button"
onClick={() => addToCart(product)}
>
Add To Cart
</button>
</div>
</Card.Content>
</Card>
</>
);
}
export default ProductCard;
这是我的 ProductCard 组件,当 addToCart 时,它将像这样转到 localStorage:
如上图,cart key
的图片是我添加的所有商品都输入的地方。即使我注销时 cartItem
仍然显示在那里,它不应该。
如果您需要更多的说明或解释,我可以提供,如果我也提供代码,我将尽可能透明。
由于每个用户都有自己独特的购物车,您可以保存购物车信息以及当前用户userId/username 作为标识符。因此,当用户登录时,您可以 使用该用户的标识符
获取他们的购物车通常对于存储此类敏感数据,最好将它们直接保存在您的数据库中而不是本地存储中。
您可以创建一个异步 Api 调用,这样每当您将商品添加到购物车时,您在 table 中的相应数据也会更新。示例“购物车”table 包含所有用户的当前购物车详细信息