reactjs - 每个用户保存或存储购物车元素的最佳方法? (最佳实践或方法)[MERNG STACK]

标签 reactjs local-storage apollo apollo-client shopping-cart

我正在尝试为我的个人项目创建电子商务,并且我正在尝试利用我所学到的一切来实现这一点。我目前有这段代码,允许您将 cartItems 存储在本地存储中,但我相信我所做的不正确,因为在这种情况下,例如 用户 1 将其商品添加到购物车或将产品添加到购物车,然后用户 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,我可以在其中查看用户添加到购物车的内容,并在需要时调用它,因为它是一个不需要的上下文将 props 传递给组件。

商店:

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 函数 传递给 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>
                &nbsp;
                <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,如下所示:

enter image description here

如上所示,图像购物车键是我添加的所有产品的输入位置。即使当我注销时, cartItem 仍然显示在那里,但它不应该显示。

如果您需要更多澄清或解释,我可以提供,如果我也会提供代码,我将尽可能保持透明。

最佳答案

由于每个用户都有自己独特的可用购物车,因此您可以将购物车信息与当前用户的用户ID/用户名一起保存为标识符。因此,当用户登录时,您只需使用用户的标识符获取他们的购物车

通常,为了存储此类敏感数据,最好将它们直接保存在数据库中,而不是本地存储中。

您可以创建异步 Api 调用,以便每当您将商品添加到购物车时,表中相应的数据也会更新。包含所有用户当前购物车详细信息的“购物车”表示例

关于reactjs - 每个用户保存或存储购物车元素的最佳方法? (最佳实践或方法)[MERNG STACK],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68689856/

相关文章:

html - Flex 填充 React 中的剩余空间

javascript - localStorage 返回 NULL

reactjs - react Apollo 错误 : No more mocked responses for the query: mutation

node.js - npm启动reactjs,无法启动,react-scripts : command not found

javascript - GatsbyJS 中的 Socket IO 客户端不起作用

iphone - iPhone Safari 上的 HTML5 - localStorage 存储的数据并不总是持久存在。为什么?

javascript - 如何使用 localStorage 保存表单数据(文本、文本区域和复选框)?

node.js - GraphQL:一个大查询与大量小查询

graphql - 有没有办法在 devtool 网络选项卡中命名 graphql 请求?

apache - create-react-app 在 LAMP/XAMPP/WAMP 上构建部署