Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 46 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ In this project you'll take take an almost completed e-commerce store and refact

### Task 1: Project Set up

- [ ] Create a forked copy of this project.
- [ ] Add your team lead as collaborator on Github.
- [ ] Clone your OWN version of the repository in your terminal.
- [ ] CD into the project base directory `cd react-shopping-cart`.
- [ ] Download project dependencies by running `npm install`.
- [ ] Start up the app using `npm start`.
- [ ] Create a new branch: git checkout -b `<firstName-lastName>`.
- [ ] Implement the project on your newly created `<firstName-lastName>` branch, committing changes regularly.
- [ ] Push commits: git push origin `<firstName-lastName>`.
- [x] Create a forked copy of this project.
- [x] Add your team lead as collaborator on Github.
- [x] Clone your OWN version of the repository in your terminal.
- [x] CD into the project base directory `cd react-shopping-cart`.
- [x] Download project dependencies by running `npm install`.
- [x] Start up the app using `npm start`.

### Task 2: MVP

Expand All @@ -40,31 +37,31 @@ Before you get started, please take a few minutes and get acquainted with this a

**Step 1 - Add item functionality**

- In `App.js` there is a function called `addItem`. Finish writing the logic in this function to be able to add the given item to the shopping cart
x- In `App.js` there is a function called `addItem`. Finish writing the logic in this function to be able to add the given item to the shopping cart

**STEP 2 - Creating ProductContext**

- In `src`, create a new folder named `contexts`, this folder is going to be used to hold all of `context objects` we create.
x- In `src`, create a new folder named `contexts`, this folder is going to be used to hold all of `context objects` we create.

- Inside that folder create a new file named `ProductContext.js`
x- Inside that folder create a new file named `ProductContext.js`

- In this file, import the `createContext` function from the react library and create our `ProductContext`.
x- In this file, import the `createContext` function from the react library and create our `ProductContext`.

**STEP 3 - Providing data with ProductContext**

- Now that we've created our `ProductContext` we can import into our `App.js`. Now we can start providing data across our application!
x- Now that we've created our `ProductContext` we can import into our `App.js`. Now we can start providing data across our application!

- Wrap all of your components/routes in `App.js` inside of `ProductContext.Provider` component.
x- Wrap all of your components/routes in `App.js` inside of `ProductContext.Provider` component.

- Next pass a value prop to your `Provider`.
x- Next pass a value prop to your `Provider`.

- In the value prop we'll pass in the products state, and an addItem function that will allow us to add books to the cart.
x- In the value prop we'll pass in the products state, and an addItem function that will allow us to add books to the cart.

```js
<ProductContext.Provider value={{ products, addItem }}>
```

- Now that we're providing our products state and addItem function we can simplify our products route a bit.
x- Now that we're providing our products state and addItem function we can simplify our products route a bit.

**Before**

Expand All @@ -82,70 +79,70 @@ Before you get started, please take a few minutes and get acquainted with this a
</Route>
```

- After refactoring you'll notice a few errors... Don't worry we'll clean those up shortly!
x- After refactoring you'll notice a few errors... Don't worry we'll clean those up shortly!

**STEP 4 - Consuming data with ProductContext**

- Now that our `ProductContext` is now providing data we can finally consume it! To do so let's head over to our `Products` component and import the `useContext` hook as well as our `ProductContext`.
x- Now that our `ProductContext` is now providing data we can finally consume it! To do so let's head over to our `Products` component and import the `useContext` hook as well as our `ProductContext`.

- In the component, call the `useContext` hook and pass in the context object we want to use into it.
x- In the component, call the `useContext` hook and pass in the context object we want to use into it.

- When we do this, `useContext` is going to return value passed by our `ProductContext` Provider `value` prop. In our case we're getting back an object with two properties. A `products` property and a `addItem` property. We can go ahead and destructure those.
x- When we do this, `useContext` is going to return value passed by our `ProductContext` Provider `value` prop. In our case we're getting back an object with two properties. A `products` property and a `addItem` property. We can go ahead and destructure those.

```js
const { products, addItem } = useContext(ProductContext);
```

- Now that we have all of the data we need we can refactor our `Products` component from using props.
x- Now that we have all of the data we need we can refactor our `Products` component from using props.

- To do so we just need to remove every instance of `props`.
x- To do so we just need to remove every instance of `props`.

- Remove it from the function parameters
- Remove it from the products map
- Remove it from addItem prop
x- Remove it from the function parameters
x- Remove it from the products map
x- Remove it from addItem prop

- Now our `Products` component is getting it's data solely from `Context API` 😃.
x- Now our `Products` component is getting it's data solely from `Context API` 😃.

**STEP 5 - Create the CartContext**

- Now that we have refactored our `Products` component to utilize `Context API` let's refactor our `Cart` and `Navigation` Component to use `Context API` as well.
x- Now that we have refactored our `Products` component to utilize `Context API` let's refactor our `Cart` and `Navigation` Component to use `Context API` as well.

- To start create a new file in our contexts folder named `CartContext.js`, this context is going to be utilized by our `ShoppingCart` and `Navigation` component.
x- To start create a new file in our contexts folder named `CartContext.js`, this context is going to be utilized by our `ShoppingCart` and `Navigation` component.

- Inside of our new `CartContext` import `createContext` and create a new context named `CartContext`.
x- Inside of our new `CartContext` import `createContext` and create a new context named `CartContext`.

**STEP 6 - Providing data with CartContext**

- Let's go ahead and bring our newly created `CartContext` into our `App.js` and wrap all of our components inside of our `CartContext.Provider`. Make sure our `ProductContext.Provider` is still the root provider.
x- Let's go ahead and bring our newly created `CartContext` into our `App.js` and wrap all of our components inside of our `CartContext.Provider`. Make sure our `ProductContext.Provider` is still the root provider.

- Now pass a value prop to our `CartContext.Provider`, this value prop is going to contain our `cart` state.
x- Now pass a value prop to our `CartContext.Provider`, this value prop is going to contain our `cart` state.

- Now that we're providing our cart data, we can start to refactor our `Navigation` and `ShoppingCart` components.
x- Now that we're providing our cart data, we can start to refactor our `Navigation` and `ShoppingCart` components.

- Let's start with our `ShoppingCart` component first. Go ahead and refactor the `ShoppingCart` route to no longer use render props. This will throw us an error, but we'll be able to resolve it quickly.
x- Let's start with our `ShoppingCart` component first. Go ahead and refactor the `ShoppingCart` route to no longer use render props. This will throw us an error, but we'll be able to resolve it quickly.

- While were at it let's go ahead and remove the props from our navigation as well.
x- While were at it let's go ahead and remove the props from our navigation as well.

**STEP 7 - The final stretch**

- Our cart data is now being provided to us from our `CartContext` time to consume it!
x- Our cart data is now being provided to us from our `CartContext` time to consume it!

- First, let's head to our `ShoppingCart` component and import the `useContext` hook and our `CartContext`.
x- First, let's head to our `ShoppingCart` component and import the `useContext` hook and our `CartContext`.

- Now in the component, pass `CartContext` to the `useContext` hook and assign it to a variable named cart.
x- Now in the component, pass `CartContext` to the `useContext` hook and assign it to a variable named cart.

- Inside of our component we now need to remove all instances of props.
x- Inside of our component we now need to remove all instances of props.

- Remove the `props` parameter
- Remove the `props` portion in our `getCartTotal` function
- Remove `props` when we're mapping over our cart
x- Remove the `props` parameter
x- Remove the `props` portion in our `getCartTotal` function
x- Remove `props` when we're mapping over our cart

- Time to do the same thing for our `Navigation` component.
- First import the `useContext` hook and our `CartContext`
- Next, pass our `CartContext` to the `useContext` hook and assign it to a variable named cart.
- Lastly we need to remove all instances of `props`
- Remove `props` from our parameters
- Remove `props` from our cart length
x- Time to do the same thing for our `Navigation` component.
x- First import the `useContext` hook and our `CartContext`
x- Next, pass our `CartContext` to the `useContext` hook and assign it to a variable named cart.
x- Lastly we need to remove all instances of `props`
x- Remove `props` from our parameters
x- Remove `props` from our cart length

We have now successfully converted our application into using `Context API` 🔥

Expand All @@ -161,8 +158,3 @@ Do not attempt stretch problems until MVP has been reached and a final commit ha

- Create a `removeItem` function that allows you to remove an item from your cart with a click of a button. This `removeItem` function should be able to be consumed from your `ShoppingCartItem` component.
Remember each item has an `id` this will help out a lot while creating your removeItem function!

- Persist Cart Items using `localStorage`. (If you try this one, it will be a bit tricky to get our items to populate the shopping cart on a refresh. You'll have to think about where the data actually lives, and how you can get data there from localStorage when the app is being mounted after a refresh. Good luck!)

## Submission Format
* [ ] Submit a Pull-Request to merge `<firstName-lastName>` Branch into `main` (student's Repo). **Please don't merge your own pull request**
27 changes: 17 additions & 10 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,35 @@ import data from './data';
import Navigation from './components/Navigation';
import Products from './components/Products';
import ShoppingCart from './components/ShoppingCart';
import ProductContext from './contexts/ProductContext';
import CartContext from './contexts/CartContext';

function App() {
const [products] = useState(data);
const [cart, setCart] = useState([]);

const addItem = item => {
// add the given item to the cart
setCart([...cart, item]);
};

return (
<div className="App">
<Navigation cart={cart} />
<ProductContext.Provider value={{products, addItem}}>
<CartContext.Provider value={{cart}}>
<div className="App">
<Navigation cart={cart} />

{/* Routes */}
<Route exact path="/">
<Products products={products} addItem={addItem} />
</Route>
{/* Routes */}
<Route exact path="/">
<Products products={products} addItem={addItem} />
</Route>

<Route path="/cart">
<ShoppingCart cart={cart} />
</Route>
</div>
<Route path="/cart">
<ShoppingCart cart={cart} />
</Route>
</div>
</CartContext.Provider>
</ProductContext.Provider>
);
}

Expand Down
11 changes: 8 additions & 3 deletions src/components/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React from 'react';
import React, { useContext } from 'react';
import { NavLink } from 'react-router-dom';

const Navigation = props => {
import CartContext from '../contexts/CartContext';

const Navigation = () => {

const { cart } = useContext(CartContext)

return (
<div className="navigation">
<NavLink to="/">Products</NavLink>
<NavLink to="/cart">
Cart <span>{props.cart.length}</span>
Cart <span>{cart.length}</span>
</NavLink>
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions src/components/Product.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';



const Product = props => {
return (
<div className="product">
Expand Down
11 changes: 7 additions & 4 deletions src/components/Products.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import React from 'react';
import React, { useContext }from 'react';
import ProductContext from '../contexts/ProductContext';

// Components
import Product from './Product';

const Products = props => {
const Products = () => {

const { products, addItem } = useContext(ProductContext)
return (
<div className="products-container">
{props.products.map(product => (
{products.map(product => (
<Product
key={product.id}
product={product}
addItem={props.addItem}
addItem={addItem}
/>
))}
</div>
Expand Down
12 changes: 8 additions & 4 deletions src/components/ShoppingCart.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React from 'react';
import React, { useContext } from 'react';
import CartContext from '../contexts/CartContext';

// Components
import Item from './ShoppingCartItem';

const ShoppingCart = props => {
const ShoppingCart = () => {

const { cart } = useContext(CartContext)

const getCartTotal = () => {
return props.cart.reduce((acc, value) => {
return cart.reduce((acc, value) => {
return acc + value.price;
}, 0).toFixed(2);
};

return (
<div className="shopping-cart">
{props.cart.map(item => (
{cart.map(item => (
<Item key={item.id} {...item} />
))}

Expand Down
5 changes: 5 additions & 0 deletions src/contexts/CartContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from "react";

const CartContext = createContext();

export default CartContext;
5 changes: 5 additions & 0 deletions src/contexts/ProductContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from "react";

const ProductContext = createContext();

export default ProductContext;