An E-commerce application built with React and JavaScript, with a focus on React Context API, and other React-based architecture, such as Hooks, Router, and component-based architecture
- JavaScript
- React
- Components
- Props
- Events
- Hooks (useState, useEffect)
- Router (react-router-dom)
- Context API
- React-Bootstrap
- CSS
- HTML
Utilizes react-router-dom
to enable client-side routing, allowing for a smooth and fast user experience by dynamically updating
the single HTML page without reloading
.
Implements React's Context API
to manage the shopping cart state globally
. This avoids prop drilling and ensures efficient state management across the application.
Built with reusable and modular components/ pages, facilitating maintainability and scalability. Each feature and page is covered within its own component, such as <Shop />
, <Product />
, <Cart />
, <CartItem />, and
.
Employs functional components and React Hooks (useState
, useEffect
) for managing state and lifecycle methods, providing a clean and modern approach to building React applications.
export const ShopContextProvider = (props) => {
const [cartItems, setCartItems] = useState(getDefaultCart());
...
};
Product data is imported from an external source and dynamically rendered within the application, demonstrating effective data management and rendering techniques.
Utilizes CSS Modules to ensure modular styles, preventing style conflicts and promoting component-specific styling.
The Context API in React is used to manage and share state across components
without prop drilling, which can make the code cleaner and easier to maintain. In this application, the ShopContextProvider
is implemented to handle the state and functionality related to the shopping cart
.
import { createContext, useState } from "react";
import { PRODUCTS } from "../products";
// Create the ShopContext
export const ShopContext = createContext(null);
// Initialize the default cart state
const getDefaultCart = () => {
let cart = {};
for (let i = 1; i <= PRODUCTS.length; i++) {
cart[i] = 0;
}
return cart;
};
-
createContext
: Creates a context object. Here,ShopContext
is created to manage theshopping cart state
and providecart-related functions
to components that consume this context.
export const ShopContextProvider = (props) => {
const [cartItems, setCartItems] = useState(getDefaultCart());
const getTotalCartAmount = () => {
let totalAmount = 0;
for (const item in cartItems) {
if (cartItems[item] > 0) {
let itemInfo = PRODUCTS.find((product) => product.id === Number(item));
totalAmount += cartItems[item] * itemInfo.price;
}
}
return totalAmount;
};
const addToCart = (itemId) => {
setCartItems((prev) => ({ ...prev, [itemId]: prev[itemId] + 1 }));
};
const removeFromCart = (itemId) => {
setCartItems((prev) => ({ ...prev, [itemId]: prev[itemId] - 1 }));
};
const updateCartItemCount = (newAmount, itemId) => {
setCartItems((prev) => ({ ...prev, [itemId]: newAmount }));
};
const checkout = () => {
setCartItems(getDefaultCart());
};
const contextValue = {
cartItems,
addToCart,
updateCartItemCount,
removeFromCart,
getTotalCartAmount,
checkout,
};
return (
<ShopContext.Provider value={contextValue}>
{props.children}
</ShopContext.Provider>
);
};
-
State Management with
useState
: TheuseState
hook is used to manage the state of the cart items. This hook provides astate variable
(cartItems
) and afunction to update it
(setCartItems
). -
Cart Functions:
addToCart
: Increases the quantity of a specific item in the cart by 1.removeFromCart
: Decreases the quantity of a specific item in the cart by 1.updateCartItemCount
: Sets the quantity of a specific item in the cart to a new value.checkout
: Resets the cart to its default state.getTotalCartAmount
: Calculates the total cost of items in the cart.
-
Context Value Object: The
contextValue object
contains thecart state and functions
to manipulate it. This object is provided to all components within theShopContext.Provider
.
return (
<ShopContext.Provider value={contextValue}>
{props.children}
</ShopContext.Provider>
);
-
ShopContext.Provider
: This componentwraps around any components that need access to the cart context
. - By passing the
contextValue
as itsvalue
, any nested component canaccess and manipulate the cart's contents
through the context API.
ShopContext
is the context object created using createContext()
. Acts as a container for the context value and provides the mechanism for React to pass data through the component tree without having to pass props down manually at every level;
import { createContext } from "react";
export const ShopContext = createContext(null);
- Purpose: To create a context object that can be used to provide and consume context data.
- Usage: It is used with the
Provider
component to make the context value available to all nested components.
contextValue
is the actual value (data and functions) that you share across components via the context. Provided to the Provider
component of ShopContext
;
const contextValue = {
cartItems,
addToCart,
updateCartItemCount,
removeFromCart,
getTotalCartAmount,
checkout,
};
return (
<ShopContext.Provider value={contextValue}>
{props.children}
</ShopContext.Provider>
);
- Purpose: To hold the state and functions that need to be accessible to all components that consume this context.
- Usage: It is passed to the
value
prop of theProvider
component to make thesestate and functions available
to any component that consumes the context.
import { Link } from 'react-router-dom';
import { ShoppingCart } from 'react-icons/fa';
<Link to="/cart">
<ShoppingCart size={32} />
</Link>
-
Link
: A component provided byreact-router-dom
to enable client-side navigation. It allows users to navigate between routes without refreshing the page.
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
<button
onClick={() => {
checkout();
navigate("/checkout");
}}
>
Checkout
</button>
-
useNavigate
: A hook provided byreact-router-dom
for programmatically navigating between routes. It enables navigation based on events or conditions in your application logic.
- Home Page: Lists products with details and options to add to the cart.
- Shopping Cart: Displays and manages items in the cart, allowing users to update quantities and proceed to checkout.
- Contact Page: A simple contact form for user inquiries.
π Demo:
screen-capture.webm
open new terminal
$ npm i
$ npm start
Tip
Feel free to dive into the code to understand the implementation details. Happy coding! πππ©βπ»
Copyright Β© Shani Bider