DEV Community

loading...
Cover image for Project 68 of 100 - Digital Image Shopping Cart with React Context + Router

Project 68 of 100 - Digital Image Shopping Cart with React Context + Router

James Hubert
Customer experience-centric product lover and front-end developer in New York. Follow my dev Twitter: www.twitter.com/jwhubert91
・3 min read

Hey! I'm on a mission to make 100 React.js projects ending May 31st. Please follow my dev.to profile or my twitter for updates and feel free to reach out if you have questions. Thanks for your support!

Link to today's deployed app: Link
Link to the repo: github

This Shutterstock-like website came with URLs for a predetermined set of images and used the React Context API for keeping track of the shopping cart and to keep track of which images the user had favorited. It's a continuation of Part 1 of this project which I posted about yesterday here.

This was the capstone project to Bob Ziroll's ~10 hour React Bootcamp course on Scrimba, which has essentially taught me React. So I'm a huge fan.

In terms of code implemented, we used a lot of the more recent features of React. This used React hooks like useState, useEffect, and useContext extensively. It also used the Context API to store state and share it between components. We built in some basic validation with PropTypes and Bob built a custom hook at the end to share a hover function for styling across the image components but this ended up being a worse solution for me than keeping it at the component state level so I commented that out.

Usually I write at length about the tech used in each project but this project used almost all the same React concepts that I used in the project I did last weekend where I wrote a massive blog post. I even predicted this capstone in a way by building in a shopping cart and handling it with the Context API. So for code I'd rather refer you to my github for this project and to the blog post I wrote up on Saturday link here.

The one thing I will post is the Context file, just because we actually created, stored, and exported more methods on that function than I ever have before.

import React,{useState,useEffect} from 'react'

const Context = React.createContext()

function ContextProvider({children}) {
  const [allPhotos,setAllPhotos] = useState([])
  const [cartItems,setCartItems] = useState([])

  const PHOTOS_URL = "https://raw.githubusercontent.com/bobziroll/scrimba-react-bootcamp-images/master/images.json"

  function toggleFavorite(id) {
    setAllPhotos(prevPhotos => {
      const photosArr = [...prevPhotos]
      const thisPhotoIdx = photosArr.findIndex(photo => photo.id === id)
      const thisPhoto = photosArr[thisPhotoIdx]
      thisPhoto.isFavorite === true ? thisPhoto.isFavorite = false : thisPhoto.isFavorite = true;
      return (photosArr)
    })
    console.log(`Image with ID ${id} favorite toggled.`)
  }

  function addToCart(newItem) {
    setCartItems(prevItems => [...prevItems, newItem])
  }

  function removeFromCart(id) {
    setCartItems(prevItems => prevItems.filter(item => item.id !== id))
  }

  useEffect(() => {
    fetch(PHOTOS_URL)
      .then((res) => res.json())
      .then((data) => setAllPhotos(data))
  },[])

  return (
    <Context.Provider value={{allPhotos,toggleFavorite,cartItems,addToCart,removeFromCart}}>
      {children}
    </Context.Provider>
  )
}

export {Context,ContextProvider}
Enter fullscreen mode Exit fullscreen mode

Granted, it's only 3 pre-built methods shared by Context to manipulate its state, but there's so much flexibility with Context it does make me excited to learn more about sharing code between components and manipulating app-wide state without passing a bunch of pesky props down all the time.

Enjoy y'all! It's on to Redux next for even more state management fun.

If you like projects like this and want to stay up to date with more, check out my Twitter @jwhubert91, I follow back! See you tomorrow for another project.

Discussion (0)