{"id":17562052,"url":"https://github.com/kidd254/myshop_react_app","last_synced_at":"2026-04-18T17:02:18.195Z","repository":{"id":223026473,"uuid":"758638641","full_name":"Kidd254/MyShop_React_App","owner":"Kidd254","description":"My Shop app is an app where users can compare prices of items, add items to cart before checkout.","archived":false,"fork":false,"pushed_at":"2024-03-02T21:16:55.000Z","size":387,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"dev2","last_synced_at":"2025-03-29T11:22:47.005Z","etag":null,"topics":["react-hooks","react-router","reactjs","tailwind-css"],"latest_commit_sha":null,"homepage":"https://myshop-react-app.onrender.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kidd254.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-16T18:42:57.000Z","updated_at":"2024-03-02T22:50:37.000Z","dependencies_parsed_at":"2025-01-03T07:46:30.758Z","dependency_job_id":"49211bd7-235c-430e-b8c2-517e0cef846f","html_url":"https://github.com/Kidd254/MyShop_React_App","commit_stats":null,"previous_names":["kidd254/myshop_react_app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Kidd254/MyShop_React_App","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kidd254%2FMyShop_React_App","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kidd254%2FMyShop_React_App/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kidd254%2FMyShop_React_App/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kidd254%2FMyShop_React_App/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kidd254","download_url":"https://codeload.github.com/Kidd254/MyShop_React_App/tar.gz/refs/heads/dev2","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kidd254%2FMyShop_React_App/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31976805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T16:27:12.723Z","status":"ssl_error","status_checked_at":"2026-04-18T16:27:11.140Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react-hooks","react-router","reactjs","tailwind-css"],"created_at":"2024-10-21T12:25:18.409Z","updated_at":"2026-04-18T17:02:18.176Z","avatar_url":"https://github.com/Kidd254.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Implementing Cart Functionality in React JS\n\n## Introduction\nIn this tutorial, we will be implementing a cart functionality in React JS. We will be using React Hooks to manage the state of the cart. We will be using the Context API to pass the cart state to the components that need it. We will be using the Local Storage API to persist the cart state in the browser.We will also be using Tailwind CSS to style our application.\n\n## Prerequisites\nTo follow along with this tutorial, you will need to have the following installed on your machine:\n- Node.js\n- npm\n\nYou also need to have a basic understanding of React JS and Tailwind CSS.\n\n## Getting Started\nTo get started, we will create a new React application using vite. To do this, run the following command in your terminal:\n\n```bash\nnpm create vite@latest\n```\n\nYou will be prompted to enter the name of your project. Enter the name of your project and press enter. In this tutorial, we will be naming our project `react-cart`. You will also be prompted to select a framework. Select `React` and press enter. You will also be prompted to select a variant. Select `Javascript` and press enter. This will create a new React application in a folder named `react-cart`. To start the application, navigate to the `react-cart` folder `cd react-card` and run the following command in your terminal:\n\n```bash\nnpm run dev\n```\n\nThis will start the application in development mode. You can now open the application in your browser by navigating to `http://localhost:5173`.\n\n## Installing Tailwind CSS\nTo install Tailwind CSS, run the following command in your terminal:\n\n```bash\nnpm install -D tailwindcss postcss autoprefixer\n```\n```bash\nnpx tailwindcss init -p\n```\n\nThis will create a `tailwind.config.js` file in the root of your project. Open the `tailwind.config.js` file and add the following code to it:\n\n```js\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}\n```\n\nNext, let's clean up the `index.css` file in the `src` folder. Open the `index.css` file and remove all the code in it. Next, add the following code to the `index.css` file:\n\n```css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n```\n\nLet's also clear up the `App.jsx` file in the `src` folder so that it looks like this:\n\n```jsx\nfunction App() {\n  return (\n    \u003c\u003e\n    \u003c/\u003e\n  )\n}\n```\nYou can also delete the `App.css` file in the `src` folder.\n\n## Creating the Products Component\nLet's create a new folder named `components` in the `src` folder. Inside the `components` folder, create a new file named `Products.jsx`.\nWe will be using the [Dummy Json](https://dummyjson.com/docs/products) to get the products that we will be displaying in our application. To fetch the products, we will be using the `useEffect` hook. We will also be using the `useState` hook to store the products in the state. Let's import the `useEffect` and `useState` hooks from the `react` package. Add the following code to the `Products.jsx` file:\n\n```jsx\nimport { useEffect, useState } from \"react\";\n```\n\nCreate a new function named `Products` and export it. Add the following code to the `Products.jsx` file:\n\n```jsx\nexport default function Products() {\n  return (\n    \u003c\u003e\n    \u003c/\u003e\n  )\n}\n```\n\n\nLet's initialize the state of the products. Add the following code to the `Products.jsx` file:\n\n```jsx\nconst [products, setProducts] = useState([]);\n```\n\nNext, let's fetch the products.We will use an `async` function to fetch the products. Add the following code to the `Products.jsx` file:\n\n\n```jsx\nasync function getProducts() {\n    const response = await fetch('https://dummyjson.com/products')  // fetch the products\n    const data = await response.json() // convert the response to json\n    setProducts(data.products) // set the products in the state to the products we fetched\n  }\n```\n\nNext, let's call the `getProducts` function in the `useEffect` hook. Add the following code to the `Products.jsx` file:\n\n```jsx\nuseEffect(() =\u003e {\n    getProducts()\n  }, [])\n```\n\nNext, let's display the products in the `Products` component. In the return statement of the `Products` component, add the following code:\n\n```jsx\n\u003cdiv className='flex flex-col justify-center bg-gray-100'\u003e\n  \u003cdiv className='flex justify-between items-center px-20 py-5'\u003e\n    \u003ch1 className='text-2xl uppercase font-bold mt-10 text-center mb-10'\u003eShop\u003c/h1\u003e\n  \u003c/div\u003e\n  \u003cdiv className='grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 px-10'\u003e\n    {\n      products.map(product =\u003e (\n        \u003cdiv key={product.id} className='bg-white shadow-md rounded-lg px-10 py-10'\u003e\n          \u003cimg src={product.thumbnail} alt={product.title} className='rounded-md h-48' /\u003e\n          \u003cdiv className='mt-4'\u003e\n            \u003ch1 className='text-lg uppercase font-bold'\u003e{product.title}\u003c/h1\u003e\n            \u003cp className='mt-2 text-gray-600 text-sm'\u003e{product.description.slice(0, 40)}...\u003c/p\u003e\n            \u003cp className='mt-2 text-gray-600'\u003e${product.price}\u003c/p\u003e\n          \u003c/div\u003e\n          \u003cdiv className='mt-6 flex justify-between items-center'\u003e\n            \u003cbutton className='px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700'\u003eAdd to cart\u003c/button\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n      ))\n    }\n  \u003c/div\u003e\n\u003c/div\u003e\n```\nThis will display a card for each product. Each card will display the product image, title, description, and price. Each card will also have a button that will be used to add the product to the cart.\n\nNavigate to `App.jsx` and import the `Products` component. Add the following code to the `App.jsx` file:\n\n```jsx\nimport Products from './components/Products'\n```\n\nNext, let's display the `Products` component in the `App` component. In the return statement of the `App` component, add the following code:\n\n```jsx\n\u003cProducts /\u003e\n```\n\nYour `App.jsx` file should now look like this:\n\n```jsx\nimport Products from './components/Products'\n\nfunction App() {\n  return (\n    \u003cProducts /\u003e\n  )\n}\n\nexport default App\n```\n\nYour `Products.jsx` file should now look like this:\n\n```jsx\nimport { useState, useEffect } from 'react'\n\n\nexport default function Products() {\n  const [products, setProducts] = useState([])\n\n  async function getProducts() {\n    const response = await fetch('https://dummyjson.com/products')\n    const data = await response.json()\n    setProducts(data.products)\n  }\n\n  useEffect(() =\u003e {\n    getProducts()\n  }, [])\n\n  return (\n    \u003cdiv className='flex flex-col justify-center bg-gray-100'\u003e\n      \u003cdiv className='flex justify-between items-center px-20 py-5'\u003e\n        \u003ch1 className='text-2xl uppercase font-bold mt-10 text-center mb-10'\u003eShop\u003c/h1\u003e\n        \u003ch1 className='text-2xl uppercase font-bold mt-10 text-center mb-10'\u003eCart\u003c/h1\u003e\n      \u003c/div\u003e\n      \u003cdiv className='grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 px-10'\u003e\n        {\n          products.map(product =\u003e (\n            \u003cdiv key={product.id} className='bg-white shadow-md rounded-lg px-10 py-10'\u003e\n              \u003cimg src={product.thumbnail} alt={product.title} className='rounded-md h-48' /\u003e\n              \u003cdiv className='mt-4'\u003e\n                \u003ch1 className='text-lg uppercase font-bold'\u003e{product.title}\u003c/h1\u003e\n                \u003cp className='mt-2 text-gray-600 text-sm'\u003e{product.description.slice(0, 40)}...\u003c/p\u003e\n                \u003cp className='mt-2 text-gray-600'\u003e${product.price}\u003c/p\u003e\n              \u003c/div\u003e\n              \u003cdiv className='mt-6 flex justify-between items-center'\u003e\n                \u003cbutton className='px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700'\u003eAdd to cart\u003c/button\u003e\n              \u003c/div\u003e\n            \u003c/div\u003e\n          ))\n        }\n      \u003c/div\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\nOpen the application in your browser and you should see the products displayed.\n![Products Page](public/cart.png)\n\n## Creating the Cart Context\nContext is a way to pass data through the component tree without having to pass props down manually at every level. In this tutorial, we will be using the Context API to pass the cart state to the components that need it. Let's create a new folder named `context` in the `src` folder. Inside the `context` folder, create a new file named `cart.jsx`. We will be using the `createContext` hook to create the cart context.We will also be using the `useState` hook to store the cart state and the `useEffect` hook to persist the cart state in the browser. Let's import the `createContext`, `useState`, and `useEffect` hooks from the `react` package. Add the following code to the `cart.jsx` file:\n\n```jsx\nimport { createContext, useState, useEffect } from 'react'\n```\n\nNext, let's create the cart context. Add the following code to the `cart.jsx` file:\n\n```jsx\nexport const CartContext = createContext()\n```\n\nNext, let's create the `CartProvider` component. Add the following code to the `cart.jsx` file:\n\n```jsx\nexport const CartProvider = ({ children }) =\u003e {\n}\n```\n\nInitialize the state of the cart. Add the following code to the `cart.jsx` file:\n\n```jsx\nconst [cartItems, setCartItems] = useState([])\n```\n\nLooking at how we want our cart to work, we want to be able to add items to the cart, remove items from the cart, and clear the cart. Let's create a function that will be used to add items to the cart. Add the following code to the `cart.jsx` file:\n\n```jsx\n const addToCart = (item) =\u003e {\n  const isItemInCart = cartItems.find((cartItem) =\u003e cartItem.id === item.id); // check if the item is already in the cart\n\n  if (isItemInCart) {\n  setCartItems(\n      cartItems.map((cartItem) =\u003e // if the item is already in the cart, increase the quantity of the item\n      cartItem.id === item.id\n          ? { ...cartItem, quantity: cartItem.quantity + 1 }\n          : cartItem // otherwise, return the cart item\n      )\n  );\n  } else {\n  setCartItems([...cartItems, { ...item, quantity: 1 }]); // if the item is not in the cart, add the item to the cart\n  }\n};\n```\nExplanation:\n- We are using the `find` method to check if the item is already in the cart. The `find` method returns the value of the first element in the array that satisfies the provided testing function. If no values satisfy the testing function, `undefined` is returned.\n- If the item is already in the cart, we are using the `map` method to increase the quantity of the item in the cart. The `map` method creates a new array populated with the results of calling a provided function on every element in the calling array.\n- If the item is not in the cart, we are using the spread operator to add the item to the cart.\n\nLet's create a function that will be used to remove items from the cart. Add the following code to the `cart.jsx` file:\n\n```jsx\n const removeFromCart = (item) =\u003e {\n  const isItemInCart = cartItems.find((cartItem) =\u003e cartItem.id === item.id);\n\n  if (isItemInCart.quantity === 1) {\n    setCartItems(cartItems.filter((cartItem) =\u003e cartItem.id !== item.id)); // if the quantity of the item is 1, remove the item from the cart\n  } else {\n    setCartItems(\n      cartItems.map((cartItem) =\u003e\n        cartItem.id === item.id\n          ? { ...cartItem, quantity: cartItem.quantity - 1 } // if the quantity of the item is greater than 1, decrease the quantity of the item\n          : cartItem\n      )\n    );\n  }\n};\n```\nExplanation:\n- We are using the `find` method to check if the item is in the cart. The `find` method returns the value of the first element in the array that satisfies the provided testing function. If no values satisfy the testing function, `undefined` is returned.\n- If the quantity of the item is 1, we are using the `filter` method to remove the item from the cart. The `filter` method creates a new array with all elements that pass the test implemented by the provided function.\n- If the quantity of the item is greater than 1, we are using the `map` method to decrease the quantity of the item in the cart. The `map` method creates a new array populated with the results of calling a provided function on every element in the calling array.\n\nLet's create a function that will be used to clear the cart. Add the following code to the `cart.jsx` file:\n\n```jsx\nconst clearCart = () =\u003e {\n  setCartItems([]); // set the cart items to an empty array\n};\n```\nExplanation:\n- We are using the `setCartItems` method to set the cart items to an empty array.\n\nLet's create a function to get the cart total. Add the following code to the `cart.jsx` file:\n\n```jsx\nconst getCartTotal = () =\u003e {\n  return cartItems.reduce((total, item) =\u003e total + item.price * item.quantity, 0); // calculate the total price of the items in the cart\n};\n```\nExplanation of the code above:\n- We are using the `reduce` method to calculate the total price of the items in the cart. The `reduce` method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.\n\nNext, let's use the `useEffect` hook to persist the cart state in the browser. Add the following code to the `cart.jsx` file:\n\n```jsx\nuseEffect(() =\u003e {\n  localStorage.setItem(\"cartItems\", JSON.stringify(cartItems));\n}, [cartItems]);\n```\nExplanation:\n- We are using the `setItem` method of the `localStorage` API to set the cart items in the browser. The `setItem` method sets the value of the specified `localStorage` item.\n- We are using the `JSON.stringify` method to convert the cart items to a string. The `JSON.stringify` method converts a JavaScript object or value to a JSON string.\n- For a real-world application, you will need to use a database to store the cart items, since the `localStorage` API is not secure and can be easily manipulated by the user.\n\nLet's also use the `useEffect` hook to get the cart items from the browser. Add the following code to the `cart.jsx` file:\n\n```jsx\nuseEffect(() =\u003e {\n    const cartItems = localStorage.getItem(\"cartItems\");\n    if (cartItems) {\n    setCartItems(JSON.parse(cartItems));\n    }\n}, []);\n```\nExplanation:\n- We are using the `getItem` method of the `localStorage` API to get the cart items from the browser. The `getItem` method returns the value of the specified `localStorage` item.\n- We are using the `JSON.parse` method to convert the cart items to an object. The `JSON.parse` method parses a JSON string, constructing the JavaScript value or object described by the string.\n\nLet's update the initial state of cart items to the cart items we get from the browser. Add the following code to the `cart.jsx` file:\n\n```jsx\nconst [cartItems, setCartItems] = useState(localStorage.getItem('cartItems') ? JSON.parse(localStorage.getItem('cartItems')) : [])\n```\nThis will set the initial state of the cart items to the cart items we get from the browser. If there are no cart items in the browser, the initial state of the cart items will be an empty array.\n\nNext, let's pass the cart state to the components that need it. Add the following code to the `cart.jsx` file:\n\n```jsx\nreturn (\n  \u003cCartContext.Provider\n    value={{\n      cartItems,\n      addToCart,\n      removeFromCart,\n      clearCart,\n      getCartTotal,\n    }}\n  \u003e\n    {children}\n  \u003c/CartContext.Provider\u003e\n);\n```\n\nYour `cart.jsx` file should now look like this:\n\n```jsx\nimport { createContext, useState, useEffect } from 'react'\n\nexport const CartContext = createContext()\n\nexport const CartProvider = ({ children }) =\u003e {\n  const [cartItems, setCartItems] = useState(localStorage.getItem('cartItems') ? JSON.parse(localStorage.getItem('cartItems')) : [])\n\n  const addToCart = (item) =\u003e {\n    const isItemInCart = cartItems.find((cartItem) =\u003e cartItem.id === item.id);\n\n    if (isItemInCart) {\n      setCartItems(\n        cartItems.map((cartItem) =\u003e\n          cartItem.id === item.id\n            ? { ...cartItem, quantity: cartItem.quantity + 1 }\n            : cartItem\n        )\n      );\n    } else {\n      setCartItems([...cartItems, { ...item, quantity: 1 }]);\n    }\n  };\n\n  const removeFromCart = (item) =\u003e {\n    const isItemInCart = cartItems.find((cartItem) =\u003e cartItem.id === item.id);\n\n    if (isItemInCart.quantity === 1) {\n      setCartItems(cartItems.filter((cartItem) =\u003e cartItem.id !== item.id));\n    } else {\n      setCartItems(\n        cartItems.map((cartItem) =\u003e\n          cartItem.id === item.id\n            ? { ...cartItem, quantity: cartItem.quantity - 1 }\n            : cartItem\n        )\n      );\n    }\n  };\n\n  const clearCart = () =\u003e {\n    setCartItems([]);\n  };\n\n  const getCartTotal = () =\u003e {\n    return cartItems.reduce((total, item) =\u003e total + item.price * item.quantity, 0);\n  };\n\n  useEffect(() =\u003e {\n    localStorage.setItem(\"cartItems\", JSON.stringify(cartItems));\n  }, [cartItems]);\n\n  useEffect(() =\u003e {\n    const cartItems = localStorage.getItem(\"cartItems\");\n    if (cartItems) {\n      setCartItems(JSON.parse(cartItems));\n    }\n  }, []);\n\n  return (\n    \u003cCartContext.Provider\n      value={{\n        cartItems,\n        addToCart,\n        removeFromCart,\n        clearCart,\n        getCartTotal,\n      }}\n    \u003e\n      {children}\n    \u003c/CartContext.Provider\u003e\n  );\n};\n```\n\n## Using the Cart Context\nNow that we have created the cart context, let's wrap the `App` component with the `CartProvider` component. Open the `main.jsx` file in the `src` folder and import the `CartProvider` component. Add the following code to the `main.jsx` file:\n\n```jsx\nimport { CartProvider } from './context/cart'\n```\nNext, let's wrap the `App` component with the `CartProvider` component. Add the following code to the `main.jsx` file:\n\n```jsx\n\u003cCartProvider\u003e\n  \u003cApp /\u003e\n\u003c/CartProvider\u003e\n```\n\nYour `main.jsx` file should now look like this:\n\n```jsx\nimport React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App.jsx'\nimport './index.css'\nimport { CartProvider } from './context/cart.jsx'\n\nReactDOM.createRoot(document.getElementById('root')).render(\n  \u003cReact.StrictMode\u003e\n    \u003cCartProvider\u003e\n      \u003cApp /\u003e\n    \u003c/CartProvider\u003e\n  \u003c/React.StrictMode\u003e,\n)\n```\n\nNext, let's import the `CartContext` from the `cart` file in the `context` folder. Add the following code to the `Products.jsx` file:\n\n```jsx\nimport { CartContext } from '../context/cart'\n```\n\nWe will also need to import the `useContext` hook from the `react` package. Update the import statement in the `Products.jsx` file to look like this:\n\n```jsx\nimport { useContext, useEffect, useState } from 'react'\n```\n\nNext, let's use the `useContext` hook to get the cart state. Add the following code to the `Products.jsx` file:\n\n```jsx\nconst { cartItems, addToCart } = useContext(CartContext)\n```\n\nNext, let's update the `addToCart` button to use the `addToCart` function from the cart context. Update the `addToCart` button to look like this:\n\n```jsx\n\u003cbutton onClick={() =\u003e addToCart(product)} className='px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700'\u003eAdd to cart\u003c/button\u003e\n```\n\nNow the button should add the product to the cart when clicked, but it's hard to visualize this without a cart page.\nLet's start by creating a `Cart` component. Create a new file named `Cart.jsx` in the `components` folder. We will be using the `useContext` hook to get the cart state. Let's import the `useContext` hook from the `react` package. Add the following code to the `Cart.jsx` file:\n\n```jsx\nimport { useContext } from 'react'\n```\n\nNext, let's import the `CartContext` from the `cart` file in the `context` folder. Add the following code to the `Cart.jsx` file:\n\n```jsx\nimport { CartContext } from '../context/cart'\n```\n\nCreate a new function named `Cart` and export it. Add the following code to the `Cart.jsx` file:\n\n```jsx\nexport default function Cart() {\n  return (\n    \u003c\u003e\n    \u003c/\u003e\n  )\n}\n```\n\nLet's use the `useContext` hook to get the cart state. Add the following code to the `Cart.jsx` file:\n\n```jsx\nconst { cartItems, addToCart, removeFromCart, clearCart, getCartTotal } = useContext(CartContext)\n```\n\nNext, let's display the cart items in the `Cart` component. In the return statement of the `Cart` component, add the following code:\n\n```jsx\n\u003cdiv className=\"flex-col flex items-center bg-white gap-8 p-10 text-black text-sm\"\u003e\n  \u003ch1 className=\"text-2xl font-bold\"\u003eCart\u003c/h1\u003e\n  \u003cdiv className=\"flex flex-col gap-4\"\u003e\n    {cartItems.map((item) =\u003e (\n      \u003cdiv className=\"flex justify-between items-center\" key={item.id}\u003e\n        \u003cdiv className=\"flex gap-4\"\u003e\n          \u003cimg src={item.thumbnail} alt={item.title} className=\"rounded-md h-24\" /\u003e\n          \u003cdiv className=\"flex flex-col\"\u003e\n            \u003ch1 className=\"text-lg font-bold\"\u003e{item.title}\u003c/h1\u003e\n            \u003cp className=\"text-gray-600\"\u003e{item.price}\u003c/p\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n        \u003cdiv className=\"flex gap-4\"\u003e\n          \u003cbutton\n            className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n            onClick={() =\u003e {\n              addToCart(item)\n            }}\n          \u003e\n            +\n          \u003c/button\u003e\n          \u003cp\u003e{item.quantity}\u003c/p\u003e\n          \u003cbutton\n            className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n            onClick={() =\u003e {\n              removeFromCart(item)\n            }}\n          \u003e\n            -\n          \u003c/button\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    ))}\n  \u003c/div\u003e\n  {\n    cartItems.length \u003e 0 ? (\n      \u003cdiv className=\"flex flex-col justify-between items-center\"\u003e\n    \u003ch1 className=\"text-lg font-bold\"\u003eTotal: ${getCartTotal()}\u003c/h1\u003e\n    \u003cbutton\n      className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n      onClick={() =\u003e {\n        clearCart()\n      }}\n    \u003e\n      Clear cart\n    \u003c/button\u003e\n  \u003c/div\u003e\n    ) : (\n      \u003ch1 className=\"text-lg font-bold\"\u003eYour cart is empty\u003c/h1\u003e\n    )\n  }\n\u003c/div\u003e\n```\n\nThis will display the cart items in the cart component. Each cart item will display the item image, title, price, and quantity. Each cart item will also have a button to increase the quantity of the item and a button to decrease the quantity of the item. The cart component will also display the total price of the items in the cart and a button to clear the cart.\n\nYou can now choose the best way to navigate to your cart from the products page using the react router. In this tutorial, we will be toggling a modal to display the cart.\nIn the `Products` component, let's import the `Cart` component. Add the following code to the `Products.jsx` file:\n\n```jsx\nimport Cart from './Cart'\n```\n\nLet's also initialize the state of the modal. Add the following code to the `Products.jsx` file:\n\n```jsx\nconst [showModal, setShowModal] = useState(false)\n```\n\nLet's create a function to toggle the modal. Add the following code to the `Products.jsx` file:\n\n```jsx\nconst toggle = () =\u003e {\n  setShowModal(!showModal)\n}\n```\n\nNext, we will add a button to toggle the modal. Add the following code to the `Products.jsx` file below the `h1` tag:\n\n```jsx\n{!showModal \u0026\u0026 \u003cbutton className='px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700'\n  onClick={toggle}\n\u003eCart ({cartItems.length})\u003c/button\u003e}\n```\nThis will display a button to toggle the modal. The button will display the number of items in the cart.\n\nLet's now display the modal( `Cart` component) when the button is clicked. Add the following code to the `Products.jsx` file just before the last closing `div` tag:\n\n```jsx\n  \u003cCart showModal={showModal} toggle={toggle} /\u003e\n```\n\nYour `Products.jsx` file should now look like this:\n\n```jsx\nimport { useState, useEffect, useContext } from 'react'\nimport { CartContext } from '../context/cart.jsx'\nimport Cart from './Cart.jsx'\n\n\nexport default function Products() {\n  const [showModal, setshowModal] = useState(false);\n  const [products, setProducts] = useState([])\n  const { cartItems, addToCart } = useContext(CartContext)\n\n  const toggle = () =\u003e {\n    setshowModal(!showModal);\n  };\n\n  async function getProducts() {\n    const response = await fetch('https://dummyjson.com/products')\n    const data = await response.json()\n    setProducts(data.products)\n  }\n\n  useEffect(() =\u003e {\n    getProducts()\n  }, [])\n\n  return (\n    \u003cdiv className='flex flex-col justify-center bg-gray-100'\u003e\n      \u003cdiv className='flex justify-between items-center px-20 py-5'\u003e\n        \u003ch1 className='text-2xl uppercase font-bold mt-10 text-center mb-10'\u003eShop\u003c/h1\u003e\n        {!showModal \u0026\u0026 \u003cbutton className='px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700'\n          onClick={toggle}\n        \u003eCart ({cartItems.length})\u003c/button\u003e}\n      \u003c/div\u003e\n      \u003cdiv className='grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 px-10'\u003e\n        {\n          products.map(product =\u003e (\n            \u003cdiv key={product.id} className='bg-white shadow-md rounded-lg px-10 py-10'\u003e\n              \u003cimg src={product.thumbnail} alt={product.title} className='rounded-md h-48' /\u003e\n              \u003cdiv className='mt-4'\u003e\n                \u003ch1 className='text-lg uppercase font-bold'\u003e{product.title}\u003c/h1\u003e\n                \u003cp className='mt-2 text-gray-600 text-sm'\u003e{product.description.slice(0, 40)}...\u003c/p\u003e\n                \u003cp className='mt-2 text-gray-600'\u003e${product.price}\u003c/p\u003e\n              \u003c/div\u003e\n              \u003cdiv className='mt-6 flex justify-between items-center'\u003e\n                \u003cbutton className='px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700'\n                  onClick={() =\u003e {\n                    addToCart(product)\n                  }\n                  }\n                \u003eAdd to cart\u003c/button\u003e\n              \u003c/div\u003e\n            \u003c/div\u003e\n          ))\n        }\n      \u003c/div\u003e\n      \u003cCart showModal={showModal} toggle={toggle} /\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\nLet's update the `Cart` component to use the `showModal` prop. Open the `Cart.jsx` file and update the `Cart` component to look like this:\n\n```jsx\nimport PropTypes from 'prop-types'\nimport { useContext } from 'react'\nimport { CartContext } from '../context/cart.jsx'\n\nexport default function Cart ({showModal, toggle}) {\n\n  const { cartItems, addToCart, removeFromCart, clearCart, getCartTotal } = useContext(CartContext)\n\n\n  return (\n    showModal \u0026\u0026 (\n      \u003cdiv className=\"flex-col flex items-center fixed inset-0 left-1/4 bg-white dark:bg-black gap-8  p-10  text-black dark:text-white font-normal uppercase text-sm\"\u003e\n        \u003ch1 className=\"text-2xl font-bold\"\u003eCart\u003c/h1\u003e\n        \u003cdiv className=\"absolute right-16 top-10\"\u003e\n          \u003cbutton\n            className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n            onClick={toggle}\n          \u003e\n            Close\n          \u003c/button\u003e\n        \u003c/div\u003e\n        \u003cdiv className=\"flex flex-col gap-4\"\u003e\n          {cartItems.map((item) =\u003e (\n            \u003cdiv className=\"flex justify-between items-center\" key={item.id}\u003e\n              \u003cdiv className=\"flex gap-4\"\u003e\n                \u003cimg src={item.thumbnail} alt={item.title} className=\"rounded-md h-24\" /\u003e\n                \u003cdiv className=\"flex flex-col\"\u003e\n                  \u003ch1 className=\"text-lg font-bold\"\u003e{item.title}\u003c/h1\u003e\n                  \u003cp className=\"text-gray-600\"\u003e{item.price}\u003c/p\u003e\n                \u003c/div\u003e\n              \u003c/div\u003e\n              \u003cdiv className=\"flex gap-4\"\u003e\n                \u003cbutton\n                  className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n                  onClick={() =\u003e {\n                    addToCart(item)\n                  }}\n                \u003e\n                  +\n                \u003c/button\u003e\n                \u003cp\u003e{item.quantity}\u003c/p\u003e\n                \u003cbutton\n                  className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n                  onClick={() =\u003e {\n                    removeFromCart(item)\n                  }}\n                \u003e\n                  -\n                \u003c/button\u003e\n              \u003c/div\u003e\n            \u003c/div\u003e\n          ))}\n        \u003c/div\u003e\n        {\n          cartItems.length \u003e 0 ? (\n            \u003cdiv className=\"flex flex-col justify-between items-center\"\u003e\n          \u003ch1 className=\"text-lg font-bold\"\u003eTotal: ${getCartTotal()}\u003c/h1\u003e\n          \u003cbutton\n            className=\"px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700\"\n            onClick={() =\u003e {\n              clearCart()\n            }}\n          \u003e\n            Clear cart\n          \u003c/button\u003e\n        \u003c/div\u003e\n          ) : (\n            \u003ch1 className=\"text-lg font-bold\"\u003eYour cart is empty\u003c/h1\u003e\n          )\n        }\n      \u003c/div\u003e\n    )\n  )\n}\n\nCart.propTypes = {\n  showModal: PropTypes.bool,\n  toggle: PropTypes.func\n}\n```\nWe have added a close button to the cart component. The close button will be used to close the cart component. and I have added some tailwind css classes to the top `div` to inset the cart component from the left side of the screen.\n\n## Conclusion\nOur application is now complete. You can open the application in your browser and test it out.\nYou should have something that looks like this:\n![React Cart Video](public/react-cart.mp4)\n\nThere are other ways you can explore to improve the user experience of the application that I won't cover e.g\n- The `Add to cart` button can change to a quantity selector when the product is already added to the cart.\n- Adding notifications to the application when a user adds/removes an item to the cart.You can use the [React Toastify](https://fkhadra.github.io/react-toastify/introduction/) library to add notifications to the application.\n\nI'll implement these features in the source code of the application. You can check it out [here](https://github.com/kidd254/MyShop)\nYou can also checkout the live demo [here](https://react-cart-azure.vercel.app/)\n\n## Resources\n- [React](https://reactjs.org/)\n- [Tailwind CSS](https://tailwindcss.com/)\n- [React Context](https://reactjs.org/docs/context.html)\n\nThank you for reading this tutorial. If you have any questions, feel free to reach out to me on [Email](mailto:lorenkioko@@gmail.com) or [LinkedIn](https://www.linkedin.com/in/Lawrence_Muema).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidd254%2Fmyshop_react_app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkidd254%2Fmyshop_react_app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidd254%2Fmyshop_react_app/lists"}