如何将变量传递给另一个组件并将其显示在另一个文件中

问题描述 投票:0回答:1

我正在尝试创建一个购物车页面。我有一个产品文件,它从 fakestoreapi 获取产品,映射它们并显示它。还有一个按钮,onClick 将产品(从获取的数据中检索到的单个产品对象)传递到另一个组件 (CarItems) 并创建包含购物车项目的 div。

我的问题是我似乎只能在产品文件页面上显示它,而不是我想要的购物车文件。

我尝试将 CartItems 组件分离到另一个文件,但这似乎阻止了任何变量传递给它。尝试使用教程中的 propTypes 但这也没有帮助。任何解决方案都只允许我在我的产品页面文件中显示购物车的商品。

产品.jsx

import { useState } from 'react'
import { useEffect } from 'react'
import './Products.css'
import NavBar from './NavBar.jsx'

function CartItems({ products }) {
    const [quantity, setQuantity] = useState(0);

    function add() {
        setQuantity(quantity + 1);
    }

    function subtract() {
        if (quantity > 0) {
            setQuantity(quantity - 1);
        }
    }

    if (products && products.length === 0) {
        console.log("Empty Cart")
        return (
            <>
                <h2>Cart is Empty</h2>
            </>
        )
        
    } else {
        console.log("Car has items")
        return (
            <div id="cartItemList">
                {products && products.map(product => (
                    <div className="cartItem" key={product.id}>
                            <img src={product.image} alt={product.title} />
                            <p>{product.title}</p>
                            <p>{product.description}</p>
                            <p>${product.price}</p>
                            <div>
                                <button onClick={subtract}>-</button>
                                <p>{quantity}</p>
                                <button onClick={add}>+</button>
                            </div>
                        </div>
                ))}
            </div>
        )
    }

}

function Products() {
    const [data, setData] = useState([]);
    const [cartProducts, setCartProducts] = useState([]);

    useEffect(() => {
        fetch('https://fakestoreapi.com/products?limit=4')
            .then(response => response.json())
            .then((data) => setData(data))
            .catch((error) => console.error(error));
    }, []);

    function addToCart(product) {
        setCartProducts(prevCart => [...prevCart, product]);
    }
    
    return (
        <>
            <NavBar />
            <div id="productsContainer">
                {data.map(product => (
                    <div className="productBoxes" key={product.id}>
                        <img className="productImg" src={product.image} alt={product.title} />
                        <h1>{product.title}</h1>
                        <p>{product.description}</p>
                        <p>${product.price}</p>
                        <button onClick={() => addToCart(product)} className="productCheck" id="productButton">Add to Cart</button>
                    </div>
                ))}
                <CartItems products={cartProducts} />
            </div>
        </>
    );
}

export { Products, CartItems };



购物车.jsx

// import { useState } from 'react'
import './Cart.css'
import NavBar from './NavBar.jsx'
import { CartItems } from './Products.jsx'

function Cart() {
    return (
        <>
            <NavBar />
            <CartItems />
        </>
    );
}


export default Cart;

应用程序.jsx

import NavBar from './NavBar.jsx'
import './App.css'

function App() {  
  return (
    <>
        <NavBar />
        <div id="hero">
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente, ullam quaerat. Dolores labore aspernatur eos, molestiae hic laboriosam, magni nostrum vel aut mollitia voluptatum ducimus nesciunt minima, voluptas ea explicabo.</p>
          <a href="products"><button>Products</button></a>
        </div>
        <footer>
          <p>Made by Christian A. Valeri</p>
        </footer>
    </>
  )
}

export default App;

Main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from './App.jsx'
import Cart from './Cart.jsx'
import {CartItems, Products} from './Products.jsx'

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: "/App",
    element: <App />,
  },
  {
    path: "/products",
    element: <Products />,
  },
  {
    path: "/cart",
    element: <Cart />,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);
reactjs variables components jsx react-props
1个回答
0
投票

现在,我想到的只有两种方法来实现你想要的。第一个是使用react-router-dom提供的useParams钩子,第二个是使用任何状态管理库,例如redux或React的内置Context API以及useState或useReducer。

我选择了 Context API + useState hook,因为它更容易让你理解,而且它的可扩展性非常好。解决办法如下:

main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from "./App";
import Cart from "./components/Cart";
import Products from "./components/Products";
import ProductContextProvider from "./context/ProductContext";

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: "/App",
    element: <App />,
  },
  {
    path: "/products",
    element: <Products />,
  },
  {
    path: "/cart",
    element: <Cart />,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <ProductContextProvider>
      <RouterProvider router={router} />
    </ProductContextProvider>
  </React.StrictMode>
);

应用程序.jsx

import { Link } from "react-router-dom";

function App() {
  return (
    <>
      <div id="hero">
        <p>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente,
          ullam quaerat. Dolores labore aspernatur eos, molestiae hic
          laboriosam, magni nostrum vel aut mollitia voluptatum ducimus nesciunt
          minima, voluptas ea explicabo.
        </p>
        <Link to="/products">
          <button>Products</button>
        </Link>
      </div>
      <footer>
        <p>Made by Christian A. Valeri</p>
      </footer>
    </>
  );
}

export default App;

以下文件位于名为“components”的文件夹中:

购物车.jsx

import { useProductContext } from "../context/ProductContext";
import CartItems from "./CartItems";

function Cart() {
  const { cartProducts } = useProductContext();
  return <CartItems products={cartProducts} />;
}

export default Cart;

CartItems.jsx

import { useState } from "react";

function CartItems({ products }) {
  const [quantity, setQuantity] = useState(0);

  function add() {
    setQuantity(quantity + 1);
  }

  function subtract() {
    if (quantity > 0) {
      setQuantity(quantity - 1);
    }
  }

  if (products && products.length === 0) {
    console.log("Empty Cart");
    return (
      <>
        <h2>Cart is Empty</h2>
      </>
    );
  } else {
    console.log("Cart has items");
    return (
      <div id="cartItemList">
        {products &&
          products.map((product) => (
            <div className="cartItem" key={product.id}>
              <img src={product.image} alt={product.title} />
              <p>{product.title}</p>
              <p>{product.description}</p>
              <p>${product.price}</p>
              <div>
                <button onClick={subtract}>-</button>
                <p>{quantity}</p>
                <button onClick={add}>+</button>
              </div>
            </div>
          ))}
      </div>
    );
  }
}

export default CartItems;

产品.jsx

import { useState } from "react";
import { useEffect } from "react";
import { useProductContext } from "../context/ProductContext";
import { Link } from "react-router-dom";

function Products() {
  const [data, setData] = useState([]);

  const { addToCart } = useProductContext();

  useEffect(() => {
    fetch("https://fakestoreapi.com/products?limit=4")
      .then((response) => response.json())
      .then((data) => setData(data))
      .catch((error) => console.error(error));
  }, []);

  return (
    <div id="productsContainer">
      {data.map((product) => (
        <div className="productBoxes" key={product.id}>
          <img className="productImg" src={product.image} alt={product.title} />
          <h1>{product.title}</h1>
          <p>{product.description}</p>
          <p>${product.price}</p>
          <button
            onClick={() => {
              addToCart(product);
              alert("Product added to cart");
            }}
            className="productCheck"
            id="productButton"
          >
            Add to Cart
          </button>
        </div>
      ))}
      <br />
      <br />
      <br />
      <br />
      <br />
      <Link to="/cart">
        <button>Checkout</button>
      </Link>
    </div>
  );
}

export default Products;

下面的文件存储在名为“context”的文件夹中:

ProductContext.jsx

import { createContext, useContext, useState } from "react";

const ProductContext = createContext([]);

function ProductContextProvider({ children }) {
  const [cartProducts, setCartProducts] = useState([]);

  const addToCart = (product) => {
    setCartProducts((prevCart) => [...prevCart, product]);
  };
  return (
    <ProductContext.Provider value={{ cartProducts, addToCart }}>
      {children}
    </ProductContext.Provider>
  );
}
export default ProductContextProvider;

function useProductContext() {
  return useContext(ProductContext);
}
export { useProductContext };

尝试一下,如果您有任何其他问题,请回复我

#react #context #react-hooks #javascript

© www.soinside.com 2019 - 2024. All rights reserved.