使用React的购物车应用

使用React的购物车应用

在本文中,我们将使用著名的JavaScript前端库ReactJS创建一个交互式和响应式购物车项目应用。我们将应用命名为 “GeeksforGeeks购物车”。开发的项目主要关注功能组件,同时管理应用的各个状态。该项目为用户提供浏览不同产品或商品、将商品添加到购物车以及进行购买的功能。用户还可以实时查看购买金额,并能够高效地删除添加到购物车的产品。

让我们动态地看一下我们的最终项目将是什么样子:

使用React的购物车应用

使用的技术和先决条件:

  • ReactJS
  • CSS
  • JSX
  • React中的函数组件

途径:

给定的代码展示了一个简单但功能完整的购物车项目,我们将其命名为“ GeeksforGeeks购物车 “。该项目完全使用ReactJS开发,并在CSS中应用样式。开发的界面允许用户执行Amazon购物车和Flipkart购物车提供的不同活动,例如浏览课程,将该课程添加到购物车,删除课程,查看实时购买金额,并投影到结账页面。在该应用程序中可以轻松集成不同的功能,例如添加付款网关或添加更多产品或课程。

项目结构:

使用React的购物车应用

package.json中的依赖关系将如下所示:

{  
  "name": "gfg-shopping-cart",  
  "version": "0.1.0",  
  "private": true,  
  "dependencies": {  
    "@testing-library/jest-dom": "^5.16.5",  
    "@testing-library/react": "^13.4.0",  
    "@testing-library/user-event": "^13.5.0",  
    "react": "^18.2.0",  
    "react-dom": "^18.2.0",  
    "react-scripts": "5.0.1",  
    "web-vitals": "^2.1.4"  
  },  

创建应用的步骤:

步骤1:VSCode IDE中使用以下命令设置React项目。

npx create-react-app <<name of project>>  

步骤2: 通过执行下面的命令,转到新创建的项目文件夹。

cd <<Name_of_project>>  

步骤3: 创建components文件夹并创建文件SearchComponent.js、ShowCourseComponent.js和UserCartComponent.js

示例: 在上述目录结构中的App.js和App.css文件中插入以下代码。

  • App.js: 该文件代表购物车应用程序的主要组件,负责管理状态和处理添加课程到购物车、删除、管理数量和结账等所有逻辑。
  • App.css 该文件包含所有样式代码,无论是h1标签的样式设置还是购物车为空消息的样式设置。整个应用程序的外观和感觉都在这个样式文件中指定。
  • SearchComponent.jsx: 该文件代码包含了搜索栏的逻辑,用户可以从中搜索指定的课程。
  • ShowCourseComponent.jsx: 该文件包含了根据用户输入显示匹配课程的代码。简而言之,课程显示的卡片是从这个文件中呈现的。
  • UserCartComponent.jsx: 该文件负责用户购物车的逻辑。在这里,通过使用不同的props,可以删除已添加的课程,用户可以选择数量并执行各种功能。
//App.js
 
import React, { useState } from 'react';
import './App.css';
import SearchComponent from './components/SearchComponent';
import ShowCourseComponent from './components/ShowCourseComponent';
import UserCartComponent from './components/UserCartComponent';
 
function App() {
    const [courses, setCourses] = useState([
        { id: 1, 
          name: 'GFG T-shirt', 
          price: 499, 
          image: 
'https://media.geeksforgeeks.org/wp-content/uploads/20230823165506/gfg1.png'
        },
        { id: 2, 
          name: 'GFG Bag', 
          price: 699, 
          image: 
'https://media.geeksforgeeks.org/wp-content/uploads/20230823165553/gfg2.jpg'
        },
        { id: 3, 
          name: 'GFG Hoodie', 
          price: 799, 
          image: 
'https://media.geeksforgeeks.org/wp-content/uploads/20230823165623/gfg3.jpg'
        }
    ]);
 
    const [cartCourses, setCartCourses] = useState([]);
    const [searchCourse, setSearchCourse] = useState('');
 
    const addCourseToCartFunction = (GFGcourse) => {
        const alreadyCourses = cartCourses
                               .find(item => item.product.id === GFGcourse.id);
        if (alreadyCourses) {
            const latestCartUpdate = cartCourses.map(item =>
                item.product.id === GFGcourse.id ? { 
                ...item, quantity: item.quantity + 1 } 
                : item
            );
            setCartCourses(latestCartUpdate);
        } else {
            setCartCourses([...cartCourses, {product: GFGcourse, quantity: 1}]);
        }
    };
 
    const deleteCourseFromCartFunction = (GFGCourse) => {
        const updatedCart = cartCourses
                            .filter(item => item.product.id !== GFGCourse.id);
        setCartCourses(updatedCart);
    };
 
    const totalAmountCalculationFunction = () => {
        return cartCourses
               .reduce((total, item) => 
                           total + item.product.price * item.quantity, 0);
    };
 
    const courseSearchUserFunction = (event) => {
        setSearchCourse(event.target.value);
    };
 
    const filterCourseFunction = courses.filter((course) =>
        course.name.toLowerCase().includes(searchCourse.toLowerCase())
    );
 
    return (
        <div className="App">
            <SearchComponent searchCourse={searchCourse} 
                             courseSearchUserFunction=
                                 {courseSearchUserFunction} />
            <main className="App-main">
                <ShowCourseComponent
                    courses={courses}
                    filterCourseFunction={filterCourseFunction}
                    addCourseToCartFunction={addCourseToCartFunction}
                />
 
                <UserCartComponent
                    cartCourses={cartCourses}
                    deleteCourseFromCartFunction={deleteCourseFromCartFunction}
                    totalAmountCalculationFunction={
                        totalAmountCalculationFunction
                    }
                    setCartCourses={setCartCourses}
                />
            </main>
        </div>
    );
}
 
export default App;

Javascript

//components/SearchComponent.js
import React from 'react';
 
function SearchComponent({ searchCourse, courseSearchUserFunction }) {
    return (
        <header className="App-header">
            <h1>GeeksforGeeks Shopping Cart</h1>
            <div className="search-bar">
                <input
                    type="text"
                    placeholder="Search for GFG Products..."
                    value={searchCourse}
                    onChange={courseSearchUserFunction}
                />
            </div>
        </header>
    );
}
 
export default SearchComponent;

JavaScript

//components/ShowCourseComponent.js
import React from 'react';
 
function ShowCourseComponent({ courses, 
    filterCourseFunction, 
    addCourseToCartFunction }) {
    return (
        <div className="product-list">
            {filterCourseFunction.length === 0 ? (
                <p className="no-results">
                    Sorry Geek, No matching Product found.
                </p>
            ) : (
                filterCourseFunction.map((product) => (
                    <div className="product" key={product.id}>
                        <img src={product.image} alt={product.name} />
                        <h2>{product.name}</h2>
                        <p>Price: ₹{product.price}</p>
                        <button
                            className="add-to-cart-button"
                            onClick={() => addCourseToCartFunction(product)}
                        >
                            Add to Shopping Cart
                        </button>
                    </div>
                ))
            )}
        </div>
    );
}
 
export default ShowCourseComponent;

JavaScript

//components/UserCartComponent.js
 
import React from 'react';
 
function UserCartComponent({
    cartCourses,
    deleteCourseFromCartFunction,
    totalAmountCalculationFunction,
    setCartCourses,
}) {
return (
<div className={`cart ${cartCourses.length > 0 ? 'active' : ''}`}>
    <h2>My Cart</h2>
    {cartCourses.length === 0 ? (
    <p className="empty-cart">Geek, your cart is empty.</p>
    ) : (
<div>
    <ul>
        {cartCourses.map((item) => (
            <li key={item.product.id} className="cart-item">
                <div>
                    <div className="item-info">
                        <div className="item-image">
                            <img src={item.product.image} 
                                 alt={item.product.name} />
                        </div>
                        <div className="item-details">
                            <h3>{item.product.name}</h3>
                            Price: ₹{item.product.price}
                        </div>
                    </div>
                    <div>
                        <div className="item-actions">
                            <button
                                className="remove-button"
                                onClick={() => 
                                deleteCourseFromCartFunction(item.product)}>
                                Remove Product
                            </button>
                            <div className="quantity">
                                <button style={{ margin: "1%" }} 
                                    onClick={(e) => {
                                    setCartCourses((prevCartCourses) => {
                                        const updatedCart = prevCartCourses.map(
                                        (prevItem) =>
                                          prevItem.product.id === item.product.id
                                                ? { ...prevItem, quantity: 
                                                item.quantity + 1 }
                                                : prevItem
                                        );
                                        return updatedCart;
                                    })
                                }}>+</button>
                                <p className='quant'>{item.quantity} </p>
                                <button 
                                    onClick={(e) => {
                                    setCartCourses((prevCartCourses) => {
                                        const updatedCart = prevCartCourses.map(
                                        (prevItem) =>
                                        prevItem.product.id === item.product.id
                                                ? { ...prevItem, quantity:
                                                Math.max(item.quantity - 1, 0) }
                                                : prevItem
                                        );
                                        return updatedCart;
                                    })
                                }}>-</button>
                            </div>
                        </div>
                    </div>
                </div>
            </li>
        ))}
    </ul>
    <div className="checkout-section">
        <div className="checkout-total">
            <p className="total">Total Amount: 
                ₹{totalAmountCalculationFunction()}
            </p>
        </div>
        <button
            className="checkout-button"
            disabled={cartCourses.length === 0 || 
            totalAmountCalculationFunction() === 0}
        >
            Proceed to Payment
        </button>
    </div>
</div>
            )}
</div>
    );
}
 
export default UserCartComponent;

CSS

/* App.css */
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #ffffff;
}
 
.App-header {
    background-color: #6cc24a;
    padding: 20px;
    color: white;
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
    text-align: center;
}
 
.App-main {
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
 
/* Search Component */
.search-bar {
    width: 100%;
    max-width: 400px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    background-color: white;
    border-radius: 20px;
    box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
    padding: 5px 10px;
}
 
.search-bar input {
    flex: 1;
    padding: 10px;
    border: none;
    border-radius: 5px;
    font-size: 16px;
    background-color: #ffffff;
    transition: background-color 0.3s ease-in-out;
}
 
.search-bar input:focus {
    outline: none;
    background-color: #ffffff;
}
 
.search-icon {
    font-size: 1.2rem;
    margin-right: 10px;
    color: #6cc24a;
}
 
/* Product Display */
.product-list {
    flex: 2;
    display: flex;
    gap: 20px;
}
 
.product {
    background-color: rgb(255, 245, 245);
    border: 1px solid #1b4e1f;
    border-radius: 10%;
    padding: 10px 60px;
    text-align: center;
    width: 33%;
    transition: transform 0.2s ease-in-out;
    cursor: pointer;
    overflow: hidden;
    position: relative;
}
 
.product:hover {
    transform: translateY(-5px) scale(1.03);
}
 
.product img {
    max-width: 150px;
    /* Increased image size */
    height: auto;
    margin-bottom: 10px;
    border-radius: 50%;
    box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.2);
    /* Enhanced box shadow */
    transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
    /* Added box shadow transition */
}
 
.product:hover img {
    transform: scale(1.1);
    z-index: 1;
    box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.3);
    /* Enhanced box shadow on hover */
}
 
.product h2 {
    font-size: 1.5rem;
    margin: 10px 0;
    color: #323754;
}
 
.product p {
    font-size: 1.1rem;
    color: #777;
    margin: 5px 0;
}
 
/* Cart Checkout */
.cart {
    flex: 1;
    min-width: 300px;
    margin-top: 3%;
    background-color: #fff9e6;
    border: 2px solid #193d10;
    border-radius: 20px;
    padding: 10px 20px;
    box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.1);
    display: none;
    position: sticky;
    top: 20px;
}
 
.cart.active {
    display: block;
}
 
.cart h2 {
    font-size: 1.8rem;
    color: #323754;
    margin-top: 0;
    text-align: center;
}
 
.cart ul {
    list-style: none;
    padding: 0;
    margin: 0;
}
 
.cart-item {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    margin: 15px 0;
    padding: 10px;
    border-bottom: 1px solid #e0e0e0;
}
 
.cart-item .item-image img {
    max-width: 90px;
    height: auto;
    margin-right: 20px;
    border-radius: 50%;
    box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
    transition: transform 0.3s ease-in-out;
}
 
.cart-item .item-image img:hover {
    transform: scale(1.1);
}
 
.cart-item .item-details {
    flex: 1;
    display: inline;
}
 
.cart-item h3 {
    display: inline;
    font-size: 1.4rem;
    margin: 0;
    color: #323754;
}
 
.cart-item p {
    font-size: 1.1rem;
    color: #777;
    margin: 5px 0;
}
 
.cart-item .item-actions {
    display: flex;
    flex-direction: row;
    align-items: center;
}
 
.cart-item .item-actions button {
    background-color: #6cc24a;
    border: none;
    color: white;
    padding: 8px 15px;
    border-radius: 20px;
    cursor: pointer;
    transition: background-color 0.3s ease-in-out;
    font-size: 1rem;
 
}
 
.cart-item .item-actions button:hover {
    background-color: #449e30;
}
 
.cart-item .quantity {
    display: flex;
    flex-direction: row;
    margin-left: 15px;
    font-size: 1rem;
    color: #323754;
}
 
.cart .total {
    font-size: 1.4rem;
    margin: 20px 0;
    text-align: right;
    color: #323754;
}
 
.cart .checkout-button {
    background-color: #6cc24a;
    border: none;
    color: white;
    padding: 10px 15px;
    border-radius: 20px;
    cursor: pointer;
    transition: background-color 0.3s ease-in-out;
    font-size: 1.2rem;
    float: left;
}
 
.cart .checkout-button:hover {
    background-color: #449e30;
}
 
.checkout-message {
    font-size: 1.4rem;
    margin-top: 30px;
    color: #6cc24a;
    text-align: center;
}
 
.no-results,
.empty-cart {
    text-align: center;
    font-size: 1.4rem;
    color: #777;
    margin-top: 20px;
}
 
@media screen and (max-width: 768px) {
    .App-main {
        flex-direction: column;
        align-items: center;
    }
 
    .product-list {
        width: 100%;
        margin-bottom: 5px;
    }
 
    .product {
        width: 50%;
    }
 
    .cart {
        min-width: unset;
        margin-top: 30px;
    }
}
 
.add-to-cart-button {
    background-color: #6cc24a;
    border: none;
    color: white;
    padding: 8px 15px;
    border-radius: 20px;
    cursor: pointer;
    transition: background-color 0.3s ease-in-out;
    font-size: 1rem;
}
 
.add-to-cart-button:hover {
    background-color: #449e30;
}
 
.item-info {
    display: flex;
    flex-direction: row;
}
 
.item-details {
    margin-top: 4%;
}
 
.item-actions .quantity p {
    margin: 10% 10%;
}
 
.product-list {
    padding-bottom: 5%;
    border-bottom: 2px solid green;
}
 
.checkout-section {
    float: right;
    margin: 0;
}
 
.checkout-section .checkout-button {
    background-color: #323754;
}
 
.checkout-section .checkout-button:hover {
    background-color: #4c5cb6;
}

运行应用程序的步骤:

1. 在终端中执行以下命令来运行应用程序。

npm start  

2. 打开像Chrome或Firefox这样的网络浏览器,在地址栏中输入以下URL。

http://localhost:3000/  

输出:

使用React的购物车应用

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程