How to build an eCommerce Website using React Redux, GraphQL, Firebase #16 – Add to Cart

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to the 16th video in this video series on building an ecommerce website using react redux graphql and firebase in today's video we're going to be working on our add to cart buttons creating our cart state within our redux store and allowing users to add products to our cart so this is a preview of what will we will have built by the end of this video tutorial as you can see we'll have a new link in our header which will take the user to our cart page beside that we'll have the total number of unique items a user has added to their cart if i add an item into the cart you'll see that that number increases i can add a different item and you'll see that the number again increases and if i add more of the same item then again that number will increase we'll also be applying the same logic to our details page so if i come down and click on the add to cart button here you'll see that that number goes up now just before we get started i just want to take this opportunity to encourage you guys to check out my official youtube channel not only to find other videos and playlists but to find the official playlist for this video series which is just a great way for you to find previous and upcoming videos in this series and keep a reference for yourself for the future again i'll be posting a link to this in the description of this video there is an official github repository for this project if you want to check out my code then again there'll be a link in the description of this video please like comment and subscribe click the bell and turn on those notifications so in this tutorial we want to set up our cart state within our redux store so that we can start to allow users to click these buttons and actually add products to their cart now although in this video we're not actually going to be building our cart page we're going to set the foundation for that so in the next video we can actually work on our cart page however i do want to give you guys something more visual by the end of this tutorial so what we will be doing is we will add a link into the navigation for our cart and i'm gonna show you how we can display the total number of unique items the user has added to their cart just beside the link itself okay so the first thing that we need to do is we need to create our new state and add that to our redux store so to do that let's head back over to our text editor and i'm going to create some new files within my redux folder so currently we have files for user and product state we want to add a new folder that will house the files for handling our cart state so i'm going to create a new folder within my cot folder for the cart sorry within the redux folder for our cart and i'm going to create some new files here so the first file i'm going to create is my cart types dot js we're also going to create a cot reducer dot js we're also going to create a cart dot actions dot js and we're going to create a cart dot utils.js file as well and we're going to be adding to these files over the course of this tutorial so the first thing that we need to set up is our types now i'm going to come into my cart.types.js file and i'm going to create a const we're going to call it cart types it's going to equal an object and at the moment our first type is going to be add to cart and again the value is going to be equal to the name of the key and then we're just going to export that so we're going to say export default cart types and this is actually the only type that we need to create for this tutorial okay so the next thing we're going to do is we're going to create the corresponding action for that type so i'm going to import the types so we'll say import cart types from and i'm going to import that from my cart types file that i just created and then we're going to create our action it's going to be a simple action that just returns an action an object with a type and payload so we'll say export const add product and this action is just going to take the next cart item and again it's just going to simply return an up an object with a type and a payload the type is going to be from cart types and add to cart and the payload of this is just going to equal the next cart item that is passed into the action and that's the only action that we need to actually create for this tutorial now that we have our add product action we're ready to build our reducer so i'm going to come over to my reducer file and i need to import my cart types so we'll import that from cart types.js and first of all we're going to build our reducer so we'll say const cart reducer and this is going to equal a function that's going to accept the state and an action now of course we need to have some initial state for our reducer so i'm going to say const initial state and this is just going to contain our cart items and by default it will be an empty array because we know that we want to store our items in an array and then we need a switch function which will take the action type and we need a default case where we will simply return the state but of course we want to have this case for adding items so i'm going to have a case for cart types dot add to cart and in this event what we're going to do for now is return an object where we use where we pass in the current state but we want to update our cart items with a new array and we're going to pass in the current items that we have so we'll pass in the state dot cart items but we want to add a new item which is the item that the user just is trying to add to uh their cart so we'll pass that in by saying action dot payload cool so at this point all we need to do is export this so we'll say export default cart reducer and then all we need to do is come over to our root reducer we need to import our new cart reducer so i'll say import cart reducer we're going to import that from our cart slash cart reducer and then what we'll do is we'll pass that into our combine reducers we're going to call it cart data and we'll simply parse the cart reducer okay so at this point we're finally ready to add in the functionality to our add to cart buttons so what we need to do is head back over to our text editor and we want to come over to our product results component this is what we use on our search page and as you can see from the code what we're currently doing is we're mapping through our product results and for each of the individual products we are rendering a nested product component right so each one of these products is actually rendering the product component now if i look at the code again if i come back into the product component itself this receives the product and it currently we are currently destructuring certain bits of information from the product the first change i'm going to make here is i'm not going to destructure anything here i'm just going to receive the entire product object and then outside of that here i'm going to destructure those items from the product itself directly now the reason i'm going to do that is because down here you can see we have the uh the the add to cart button that's where we're rendering it now what we want to do is whenever this is clicked we need to call a function i'm going to call this this function handle add to cart and what this is going to do is it's going to take the product right that we're going to pass to the function when it's cold so on the on click event of our button here so on the unclick event right we're going to call handle add to cart and we're going to pass in the entire product object that the component receives so within this function we can do a couple of things we can check that it receives the product if it doesn't get a product we can return immediately so that's a god that we're going to add in but then we need to dispatch the action so i'm going to need to import something from react redux which is the use dispatch hook that's how we can access and use dispatch within the component so i'll say const dispatch equals the use dispatch hook called as a function that will pop that will give us access to dispatch so within my handle add to cart function i can call dispatch but we also need of course the action itself that we want to dispatch so i need to import that from my uh redux folder in the cart folder and in the cart actions and of course this is just called add add product so we can dispatch this action and we can pass we can pass the entire product object to the add product action okay so at this point we're ready to actually look at what this look at this in the browser and although we're not actually rendering our cart items anywhere at the moment what i can do is i can open up my console and what i'll do is i'll just scroll down here and if i add something to the cart what you're going to see is the the previous state here so you can see that previously the cart data array the cart items array sorry was empty it had nothing and if i come into the current state the next state you'll see that the cart data and cart items has one right and this is the entire product object that we passed to our action that we dispatched and of course i can add multiple items here so i could add two or three more products and again if i look at that state you'll see that we have all of those three items that i added but there is a problem here right which you may or may not have considered and that is what about what happens if i add two or more of the same product right so what if for example i added two or three of the same product to the cart right so if i look at the state now you'll see that it's added those items again and again right there's no quantity here we're constantly adding the same product to this array again and again and this is something that we need to fix okay so let's come back over to our text editor and look at the code we're going to go into our cart reducer so it's in cart and cart reducer.js and what we're currently doing is we're simply returning a new piece of state where we get the current cart items and we return we add the new item right we're not checking to see if the item that we're trying to add already exists within our cart items array we're just adding the same product again and again so we need to first of all check to see if that item exists and then if it does we want to update a quantity field and if it does not then we'll just add it at that point now if that doesn't make sense right now then just bear with me hopefully it will as we move through the tutorial it's actually not that complicated once you get the idea of what we're going to do but i do want to create a small abstraction and that's why i have this cart utils file because we're going to write a utility function that will handle this for us in a nice clean way so let's just create the skeleton of that function before we do anything we're going to need to remember to export it but we're going to call this handle add add to cart right it's a util function and this is going to expect two things right it's going to expect the previous i'm going to call it prev cart items and it's going to expect the next cart item right those are the two things that we need to remember to pause to this utility function so now i've created this i'm going to import that into my cart reducer file so i'll just import handle add to cart right so we'll say import from the cart utils file and then what we need to do is rather than return an array here we're going to call our utility function but we need to pass in the values it requires so it requires the prev card items right and that is going to be equal to our state dot cart items and we also are going to pass our next cart item which again is going to be the action dot dot payload right so once we've passed those two things to our utility function here um we're going to have to do a couple of things but first of all let's just handle the case where the uh the item we're trying to add does not exist in our cart right so it's a new product that hasn't been added to our cart before well in this case we're simply going to return again a new array we're going to pass in the previous cart items and we're going to create a new object here on our cart state and we're going to get all of the data from our next cart item but we want to add a new field which is called quantity right and by default we're going to set this to 1 right but i'm not actually just going to assign that as a hard-coded value i like to store that in a constant at the top of the function so i'm going to call this the quantity increment and assign that as as a value of one so whenever we call this we're going to increment this by one okay so this handles the use case where a user adds a new product to their cart but there is that there is the additional case where the item does exist where they're adding the same product to their cart where we would want to to increase the quantity field for that cart item so to do that we need to be able to check with an ifs with a conditional here if the item exists or not and then handle that scenario so to do that i'm going to actually create i'm going to a separate function because it's a useful function to have i'm going to separate it i'm going to create another function here so i'll say export cons i'm going to call this existing cart item right it's going to expect two things right it's going to expect the previous again i'm going to call it the same thing so previous cart items and the next cart item right it requires the same two things and then we need to evaluate this conditionally right so we'll say we'll just return here and we're going to say if we're going to search our previous cart items array so we'll use the find method for that we that that that we have from arrays that we can use on arrays because of course this is of type array and what i'm going to do is i'm going to get the current cart item right and then i'm going to evaluate against the document ids so i'm going to take the current cart item dot document id and compare that with the next cart item document id and it's actually as simple as that right so all we're doing here is we're going to check if the item the document ids match that will evaluate to a boolean value of either true or false so what i can do is i can actually store that in a const here within my handle add cart function so what i can do is i can call existing cart item here and i'm going to just assign this to a a cons i'm going to call this cart item exists right and i'm going to call this fi this this function and of course we need to pass in these two values so we need to pass in the previous card items in the next cart item but that will return either true or false and i can pause i can use that within my if statement here and if this if this hits if this returns true then the code inside of this will run if the cart item we're trying to add already exists within my cart right so at this point what i need to do is find the matching the the cart item that we're trying to add i need to find that within my current cart and i need to increase the quantity value on that item right so what i'll do is i'm going to return this so i'll return here and i'm going to map my previous card items i'm going to map here i'm going to get the cart item right and then what i want to do i want to evaluate this on the cart item dot document id and i want to evaluate that against the next card item document id and if if this is true if it matches it means that this is the same card item that we're trying to add we're adding the same item again in which case i'm going to pass the cart item but i'm going to get the quantity right and what i'll do is i'll set this to the current item dot quantity and i'm going to add the quantity increment which is one so i'm adding one to the current quantity now if this returns false which is feasible it means that um we're currently mapping over an item in the cart that is not the one that we're trying to add right so although the item exists in the cart we're currently we're mapping all of the items in the cart and we're currently on an item that is not the same as we're trying to add so in this case all i'm going to do is i'm actually not going to return an object here what i'll do is i'll just return the the cart item so absolutely this is a little bit more complicated it's not so simple but this is all we need to do here so i'm going to save those changes and i'm going to come back over to the web browser i'm just going to reload this and i'm going to come back into my my console and i'm gonna scroll down here and click on add to cart so i'm adding the men's product one here i'm adding that to my cart and let's look again let's look at our state here and you can see i've just added a cart item and if i show you this object you'll see i have a quantity value of one and if i add the same item again to my cart what i should have if i show you the state is i still only have one item in the cart but the quantity value is two okay so again i can still add other items let's add this men's product to let's look in the cot items state you'll see i now have two items this one has a quantity of one and this one has a quantity of two so you can see i'm now able to add multiple items to my cart however i'm not going to constantly re-add the same items to the cart i have a quantity value assigned to it okay so at this point we've handled our add to cart button on our search page but we haven't applied the same logic to our product details page but this is really easy for us to do so all i'm going to do is i'm going to come back over to my text editor i'm going to go into the code and into the components folder and of course our product details page uses our product cod component this was a component we built in a few tutorials ago and the first thing i need to do is i need to import the action that i created to add the product to our cart so i can import that from my redux folder it's in the cot folder and in my cart actions file and it's called add product now we're already dispatching other actions on this component so all i need to do here is come down to where we're rendering our add to cart button i'm going to add the on click event and on the click event we're going to call a function i'm going to create that function up here so i'll just say const handle add to cart again it's going to take the product and we're going to check if the product has been passed if it hasn't we're going to return null immediately out of this function otherwise we're going to call dispatch and we're going to call we're going to dispatch our add product action and we're going to pass in our product now again i'm just going to remind you guys that already up here where we are um we are getting our product so it's actually available here on our uh on our component and all i'm going to do is i'm going to call in the onclick event the handle add to cart function and i'm going to pass in the product right that has already been passed to the component so that's what we actually need to do here let's come back over to the browser let's open up the console and what i'm going to do is i'm just going to add click on this add to cart button let's check the state and you can see the cart items contain the product we just added and again there's the quantity value of one okay so i already mentioned earlier in this video that i wanted to give you guys something visual by the end of this tutorial because we're not going to be building our cart page until the next tutorial so what we're going to do now that we have added in the functionality and the logic to handle actually adding products to our cart and setting up our cart state within our redux store what we're going to do is we're going to add a link into our header and our navigation that will eventually take the user to the cart page that we create again in the next tutorial but in this tutorial we're going to create we're going to display the total number of unique items beside the link that we create in the navigation the total number of unique items that we have in our cart so to do that what we're going to do is just come over to our code and we're going to go into our header component i have that here so currently we we are rendering our call to actions which if i show you is the links on the right side of the header here right which just contain either register and log in or if you are looked in it it displays my account and log out so this is currently two unordered lists based on these this condition here what i'm going to do is i'm going to refactor this a little bit i'm going to merge this that we only have one unordered list right and what i'm going to do is i'm just going to say that we either render this but we're going to remove the unordered list right so we're just going to return the basic list items rather than the list itself here now of course here we have to return an array right because we're not going to have a single wrapper so in this case we return an array and then on here because in jsx you you have to return a single element but in this case because i'm now returning an array i can return two separate elements right as long as i s i i set a come up between them right and i'm going to do the same thing here where we render links when a user is not signed in right so again i need to make sure i return an array i'm going to remove the unordered list and we are going to add in a comma here between the list items and yeah that looks much better okay so again let's just check this in the browser and everything still looks the same that's a good sign but what that will allow us to do is add a new link and a new list item into our call to actions and we are going to create a new link a a link effectively for the user's cart so we'll say your cart and what we want to do is just save that and come back over to the web browser and what you'll see is we now have this link to our cart now if you click it doesn't do anything because we haven't defined the path for the link component but beside this what we want to do is we want to get the total number of unique items that we currently have within our cart and to do that we're going to have to install a new library right and i'm going to explain what that is and how to use it shortly but first of all let's just come over to our terminal and what we're going to install is called reselect so i'm going to i'm going to type in here npm install reselect and i'm going to go ahead and install that dependency and it might take a few seconds and once that's installed let's just restart the application and return over to the web browser the next thing that we need to do is find a way to get the total number of unique items from our card and display that beside our link for our card in our in our header so to do that let's come back over to the code and into our header.js file and as you can see here some of the work has already been taken care of for us because we're already mapping state to the component using the use selector hook and this is our map state function so we can actually perform some action within this right so what we want to do is we want to get our cart data this is our this is our cart state from our redux store and then what we want to do is we want to get the total number of cart items and at this point we could do something like for example cartdata.cart items and because this is an array we could say something like length right and this would return the total number of uh items within our cart items array but the problem is if you look at our cart utils you'll remember that we have this quantity field so although there may be a certain number of items within our array we may have more than one in this quantity field that we need to account for so what that means is we need to perform a slightly more complicated action here to find out the true value of the total number of items in our cart and of course that is going to require us to write a custom function or some find some way of doing that and that's going to take resources that's going to slightly impact performance so to truly optimize this we want to find a way so that whenever this component re-renders we don't run this code unless something has actually changed in the cart state so we want to remember we want to memorize the the value of the total number of cart items and only change this value if uh something in our cart has changed if they've added another item if they've removed an item if they've changed the quantity of an item that is the only time we want to adjust this value and that is why i asked you guys to install the reselect library which is what we're going to use here because it allows us to write custom redux selectors so i'm going to come down here into my redux folder and into the cart folder and i'm going to create a new file i'm going to call this my cart dot selectors dot js and the first thing that we need to do is we need to import our well we need to import something from reselect itself which is create selector and then what we'll do is we need to first of all we need to get the cart data so i'm going to create a const here and it's a naming convention within reselect and when we create our selectors right to prefix our selectors with select right so we're going to say in this case because we want to get our cart data state from a redux store we'll say select cart data where we just get the state and return the state dot cart data okay and then we're going to create our first selector so we'll just say const select cart items right it's going to equal create selector we're going to pause our select uh we're going to pause select cart data and then we'll get the cart data and we're going to return cart data and dot cart items which is our cart items array that we're storing within our redux store and our cart state and then what we want to do is create a custom selector for to find out how many unique items we have within our redux store and within our cart state so to do that i'm going to create a i'm going to export const select cart items count and we're going to call create selector we're going to pass in our selector to get our cart items and then we're simply going to get the card items and we're going to call reduce on our cart items array so we'll say cart items reduce and then what we want to do is we want to get the accumulated value so to do that we'll call we'll get the quantity and the current cart item and then what we'll do is we'll just create a simple calculation we'll get the quantity again and we'll plus the card item right the cart item and we'll look at the quantity field and of course by default we want to make sure that the default value is of course is of course zero okay cool so that's our custom selector and that's how we're gonna get the total number of unique items from our cart state i'm going to export these as well in case we want to use them in other places but for now that's fine and then i'm going to come back over to my header and i'm going to use and i'm going to use that custom selector within my header component so to do that all i need to do is import it so we're going to import from our redux folder our cart folder and our cart selectors and again we want to import select cart items cart items count and then we're going to call this within our map state function but we're going to pass in the state so now rather than destructure the state values here i'm just going to get the state because we need to pass the entire state into our custom selector so here i'm going to prefix this with state dot user.currentuser so that should be fine so we now have access to the total number of unique items so i'm gonna i'm gonna destructure that from what our use selector returns our use selector hook and then i'll come down and where we are rendering our cart link i'm going to render the total number of items in the cart okay so let's come back over to the browser let's reload the page and let's add some items to the cart so you can see up here it says zero currently let's add an item you'll see it goes to one let's add another item here a different product goes to two let's add the same product which is the first product here and it goes to three so you can see that it's taking into account the total number of unique items and the quantity field right and you can see that it's working very nicely at this point users are able to add items into their cart in the next video we're going to be building our cart page this is where users will be able to view the items they have in their cart adjust the quantity of the items they've selected and eventually check out using stripe but that does bring this tutorial to an end but before we sign off i just want to remind you guys there is an official github repository for this project at the end of each of my videos i create pull requests i merge my code into the code base so if you guys want to compare your code with mine or you just want to clone the entire project feel free to check this out i'll be posting a link in the description of this video as always i want to remind you guys to check out my official youtube channel that's youtube.com forward slash simpletut not only to browse my other videos and playlists but also to find the official playlist for this video series this is just a really easy way for you to find the previous and next videos in this series and just keep a reference for the future but as always i just want to ask you guys to like comment and subscribe your support means a lot but again thank you very much for watching i look forward to working with you in the next video
Info
Channel: SimpleTut
Views: 3,470
Rating: undefined out of 5
Keywords: ecommerce, react, react redux, GraphQL, React Context API, Node, Node JS, redux, online store, stripe, stripe api, shopping card, paypal, firebase, react router, react router dom, routes, routing, Google Sign-In, Google Auth, Google Sign In Authentication, login, signin, react hooks, useEffect, useSelector, useDispatch, redux hooks, useState, add to cart, checkout, stripe payments
Id: Q831pCJMnT0
Channel Id: undefined
Length: 41min 50sec (2510 seconds)
Published: Sat Oct 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.