How To Create An Advanced Shopping Cart With React and TypeScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video i'm not only going to be building an advanced shopping cart using typescript and react but i'm also going to be structuring this project like a real world large scale project and that means that i'm going to have advanced file structure folder structure naming conventions best practices and so on that you can pick up on so you can learn so much more than just how to build a shopping cart [Music] welcome back to web dev simplified my name is kyle and my job is to simplify the web for you so you can start building your dream project sooner and here is the working version of our final project you can see we have multiple different pages the only page that has any content is the store page but the important thing is if we add things to the cart we can go to a different page we can still open up the cart and interact with it we go back to our store and those changes are going to take effect so the shopping cart is going to work across multiple pages there's multiple ways to interact for example plus minus buttons you can remove things by clicking this remove button you can remove things from within the shopping cart and so on so it's a really fluid system that you can really slot into any project you need and best of all in this tutorial i'm going to be going over a lot of advanced features for building larger scale projects which you can incorporate into your own project now to get started with this project we're going to be using veet to create our react application instead of create react app and it's just because i think it has better support for things like typescript and it just works really well so to do that we just need to run npm create and veet and then we just want to put a period here which says create the project in the current folder now when i run that it's going to ask me what i want to call this package we're just going to call it shopping cart and then we want to use react and we want to use the typescript version of react so once we do that we can just run the install method and then we can type npm rundev and that's going to give us just a boilerplate code and if we look in this source folder you'll see a lot of this looks really familiar this is very very similar to the create react app template it just has a few extra changes to it but overall it's almost exactly the same now we don't need all these files so we can get rid of things like the logo that's app.css we can get rid of essentially everything inside of here we can just return let's just do an h1 that says i there we go and we can get rid of the favicon this css this we don't need that css and we don't need that css so we pretty much got rid of everything but in h1 and if we save all of these files now type npm run dev that's going to run the development version of this for us and if we go to localhost 3001 you can see that it just says hi right here and we still have this test version open so we can compare between the two different versions now before we get too much further into the shopping cart i do want to install some libraries that we're going to be using for this project so the libraries that we're going to be using is we're going to have react router for all of our routing so we're going to say npm i react router dom that's for our routing for our different pages and also we're going to need to have bootstrap for our styling you can use anything you want for styling i just figured bootstrap is going to be the easiest we need bootstrap and react bootstrap to make working with it and react a little bit easier so once we install those all we need to do is actually implement those into our application and first we want to import our css for bootstrap which we can do right in this file to do this import all we need to do is say import bootstrap we want to go to the distribution folder and we want to go to the css folder and we want to import bootstrap.min.css and if we save that and run our application we should hopefully see that over here the styling for this high actually changes slightly there you go you can see it's a different font now so that's how we know that our bootstrap css is actually being imported now the next thing that i want to do is actually implement our folder structure because this is a folder structure you can probably follow in most applications you work on the very first folder i want to create is called components and this is where all of our components are going to go things like our shopping cart our shopping cart items and so on the next folder that we want to create here is going to be for our pages and if we come over here you know we have a home page a store page and about page this is for representing those different pages those high level routes in our application next we're going to have a folder that's going to just be for data this is a folder that's going to contain any like json data we need for example our store items are all json data by default so we can just put our store data in that data folder also we're going to want to have a folder here for different context in your application you almost always have different react context or redux context that you're going to be working with in our case our entire shopping cart is going to fit inside of a context that we're going to put inside this folder another folder i like to have is called a hooks folder this is for all your custom hooks such as use local storage which is a hook we're going to be using this project to make sure that if we add something to our cart and refresh our page it's going to stay in our cart another thing that we want to be able to implement in this project is going to be a folder for utilities so if we have different utility functions that do small things like formatting our currency that we want to do all over the place we can put that in this utilities folder now that right there is like the most basic of all folder structures that you can think of you can obviously add and remove folders as you need but for our project this is going to work perfectly the very first thing i want to work on in our project is going to be our routing so to do routing inside of react router we first need to import our router which is a browser router and that comes from react router dom just like that and this browser router just needs to wrap our entire application so we're just going to wrap our application like this and now our entire application is inside of this router now to use this router we're going to go into our app.txx and this file essentially is going to contain all of our routes and all of our generic code that goes outside of all of our routes for example our about page our home page our store page those are all of our routes but this nav bar right here is included in all of our routes so it's going to be put inside of our app as well so inside of here what we want to do is we want to import all of our stuff for routing and all of our different components so we can go up to the top here what i want to do is i want to import routes and route and these are going to be the different components we're going to use for our routing that comes from react router dom and then also i want to import here the container component and that's coming from react bootstrap so we can just wrap our entire thing inside of a container like this so now if we save we go back over here and we just wait for this to load up for a second give it a refresh maybe there we go you can see that now we're inside of a container and as we expand our screen you can see that it's kind of staying centered like that which is exactly what we want so it looks really good make that a little bit smaller now we can actually work on our router which is going to be pretty straightforward all we need to do is say that we're going to have a bunch of routes inside of this we want to have individual route components and these all have a path which indicates where on the page we are so for example our home page is just going to be the slash route and then we have an element and this element corresponds to the actual component we want to render so we're going to have a home component then we're going to have a bunch of other routes for our different components for example we're going to have a store and we're going to have an about page and this one is going to be at store and this one is at slash about really straightforward all we need to do is create these three components themselves so we can render them on our page so let's do that inside of this pages component here we can create a home.tsx and inside of here we're just going to export a function called home and all this is going to do is return to us let's just say maybe an h1 that says home super straightforward that's all that this component does and now we can import that component here we just do that we can import home from pages and now we have that home page now you will notice i'm doing export function instead of export default function i find that when you're working on larger projects having all your exports be named is a little bit easier to keep track of everything so that's why i'm doing that let's copy this file a couple times we're going to have our store and we're also going to have our about i just want to change these to about and the store one is going to say store so now we have our three different pages if we save our application and make sure we import these just like this let me give it a save you can see it now says home if we go to store you can see it says store and if we go to slash about if i can spell it properly you can see that we're on the about page now the final thing that i want to do inside of our container is i want to add a little bit of margin on the bottom so we're going to say class name here is mb4 that's just going to add some margin to the bottom of our container so if it's really long it doesn't touch the edge of the screen it has a little bit of spacing now the reason i'm not adding any margin to the top is because the next thing we want to do is create our own nav bar and bootstrap has like some nav bar classes we can use but instead of doing that inside of our app i want to create our own component for our navbar so inside of here i'm going to create a new file called navbar.tsx and this is going to be explicitly for our navbar component then inside of our app i want to import that component so we're going to say import nav bar it's going to be coming from that file which is dot slash components slash nav bar there we go and then we can just render that nav bar whoops nav bar just like that we need to put that inside of a fragment so we can render everything to the screen there we go now we obviously just need to make this nav bar actually work so we can say export function nav bar and for now if we just return an h1 that says nav and we save you can see our nav is showing up now to create a nav bar using bootstrap is really easy we have a component called navbar that we can actually use but we first need to import this component and since it has the same name as our navbar component we need to rename it to something else so i'll show you exactly what i'm talking about we're importing this from react bootstrap and we want to import a component called nav bar but of course these two things have the same name so that's a problem so we're going to import this with the name of navbar bs just so we know this is our bootstrap navbar and now we can use this nav bar down here so we have that bootstrap nav bar which inside of it we're going to contain all of our information so first i'm going to put everything inside of a container so we have the same kind of sizing information that we have for the rest of our application so if i just put the text nav in there for now you can see that this nav is in the same container as like our about page but on our navbar i want to give it a background and a shadow so we can say here we're going to go class name background white and we're going to say shadow small and let's give it a little bit of margin on the bottom and now you can see it's giving it a little bit of a shadow if i make this shadow like large for example you can see a very large shadow i think small looks the best now one thing that you'll notice is our navbar is white and our page is white that makes it a little bit hard to see what the difference between the two is so inside of our index html on the body i want to come in here and add a class of background light it's just going to give us a slightly off-white background color and we're going to have to refresh our page for that to see through but you can see we have this slightly different white color down here than we have up at the top it's just slightly grayer so that gives us a little bit of contrast which is going to look really good when we start getting our cards showing up on the page as well so now inside of our nav we need to create essentially all of our different links as well as the shopping cart button you can see we have our links on the left shopping cart button on the right pretty straight forward to do inside of here we're going to use a component called nav which comes from that bootstrap library up here and inside this nav component we're just going to put links so we can say nav dot link and this nav dot link we're going to make it act like it's a nav link from react router now in order to do that we just need to use the as tag here so we can say as and then we just need to say what we want it to act like and we want it to act like that nav link so this is called nav link and this comes from react router dom just like that now all we need to do is give it a two property which is a property of nav link that'll tell it where we want to actually send this link to in our case this is going to be our home link so we're just going to use the slash path right here for our home we can close this off and then we can type in home and if i save this real quick you'll now see we have a home link up here and when i click on that it brings us to the home page now we just need to copy this down to do this two other times for both of our other links so we can say here that we have a store link and we have an about link and we want this to go to the store page and we want this to go to the about page now if i give this a save you can see we have our home our store and our about page and we can navigate between all of them the next thing we need to do with our nav bar is we need to add a section on the right hand side for our shopping cart button to do this i'm just going to emulate that by putting the text high right here and then to make sure that this high text is always pushed the right hand side no matter what on our nav i'm going to come in here with a class name i'm just going to say this is going to be me auto and that's just going to put margin on the right hand side of our nav bar so that it fills the entire space and pushes whatever we have on the right all the way to the right side now instead of just rendering the text high we're going to render a button straight from react bootstrap we're going to import that up there and inside this button what i want to do is i want to put an svg now you can go online and find any svg you want for the shopping cart i'm just going to copy and paste an svg that i found by just searching for an svg for a shopping cart and if i save you're going to notice nothing shows up right away because i haven't given any size but as soon as we give it a width and a height it's actually going to show up on the page and again you can find any svg you want it really doesn't matter or if you want you can go to the github linked in the description and copy this exact svg if you want to use the same one for your project so what we need to do is add some styles and we want to change the width which we're going to say is 3rem and we're going to change the height which we're also going to say is 3 ram just doing that alone you can now see that we have our shopping cart icon showing up inside of our button i want to change our button quite a bit to make it look a little bit better so what we're going to do is we're going to change the variant here and it's going to be outline primary that's just going to give us an outline instead of the actual solid version and i want to add some classes here and i want to make it rounded so we're going to say rounded circle that's going to make the button a circle shape which i like and then eventually we want to add an on click into this but for now we don't want to worry about that the only other thing i want to worry about is having the indicator right here telling me how many items are in my cart as i add more and more items to the cart this number is going to change and i want to have an indicator for that so to do that we're just going to need to put essentially a red circle inside of our button and to position that we're going to use absolute positioning so we need to make our button itself a relative position to make styling and rendering out the button and there the red circle i'm sorry inside of our button in the right location so now i'm trying to collapse down this svg because afterwards i'm just going to have a div in this div all it's going to do is have a number for example 3 inside of it for how many items are in our shopping cart and then we're going to have a bunch of classes and styles applied to this so i want to make this a circle as well so we're going to say rounded circle i want to make it a red background so we're going to give it background danger and i want to center everything so we're going to use flexbox for that we can say justify content center and align items center and that's going to center that for us at least now all we need to do is position this red circle as far to the right as we can essentially that bottom right hand corner so inside of our style let's go ahead and do that we're going to change our color here to white that's just going to be so our text is white we're going to change our width here to 1.5 rem essentially half the size of our overall button same thing for our height 1.5 rem just like that then what i want to do is i want to use position absolute and that's allowing us to give it a bottom and a right position so we're going to say bottom is 0 right is 0. and if we just save this alone it's not going to be quite in the right location because our bottom right of our circle is in the bottom right of this circle we want to offset it a little bit so we can just do a transform whoops transform and the translate and we're just going to say negative 25 percent in both directions and that is going to just put it in the right location i'm sorry positive 25 in both directions and as you can see that puts it in the bottom right hand corner pretty much exactly where we want you can tweak these numbers if you want in a slightly different position now obviously we want these numbers to be dynamic but we're going to cover that in a little bit the only last thing i want to do style wise is i want to make my nav bar sticky so i want to say sticky top and that's just going to make it so it sticks to the top of the page so when we scroll our navbar is always going to be visible now the next thing i want to work on is on our store i want to actually render out all these different store items i'm not going to worry about the functionality we just want to get the styling in place first and then we can add the functionality in on top it makes it a lot easier to work this way in my opinion so in order to do that let's just close out of all the files we currently have open come over here and you're going to see that we have our store page we go to our store page and here we can actually render out all this information now to get this information it's going to be coming from a json file so i'm actually just going to copy over all the json i'm using we can just come in here create a new file called items.json and i'll just show you what's inside here essentially we just have four different items they all have an id they have a name they have a price and then they have an image url so we also need to bring in all of those images now these images are going to go inside of a public folder so that we can access them so we're going to create a public folder and this public folder must be on the outside of your application outside of the source folder and inside of here we're going to create another folder called images and in this images folder i'm going to put all of our images which i'm just going to copy all of them over so that there we go we have a banana image we have our book image a car image and a computer image pretty straightforward stuff now that's how our json file is laid out it just has the pricing id name and image url and we're going to take that information and create these cards with that information so let's go back into this store page here and the first thing i want to do is i want to import all those items so we can just say import store items from and we want to go to whoops dot dot slash data slash items.json now that right there is going to give us all of our store items that's perfect now the next thing that we need to do is actually render them to our page so we're going to keep our title here of store i'm just going to come in here with some fragments and then below that i want to create a row and inside this row we're going to have a column and we're going to have one column for each one of the items inside of our store items so let's just import row and import column so we can actually use these and which give it a quick save here there we go now inside of here we want to do essentially a for loop over our store items so we can say store items dot map for each one of our items what i want to do is i want to render out a component and this component is going to be inside of a column so we're going to bring our column up to here and then inside of this column we want to render something out for now i'm just going to say json.stringify our item there we go and now that's essentially all we need to do for that and if we just give this a quick save we go over to our store page you can see each one of our items is being rendered out inside of the row that's really good now the next thing i want to do is i want to change our row because we want this to be like a grid so as you can see as i expand my page we get more and more items shown on our page at a time depending on how large or small our screen is and we can do that really easily by saying at the medium screen size for example we want to have two columns at the extra small screen size we want to have one column and as a large screen size we want to have three columns that right there is going to give us this column layout also i want to add a single class name of g3 and that's going to give us a gap of three so it's just going to give us space on the vertical and horizontal direction between each one of the elements in our rows now if we look over here you can see we have space and as i expand my screen we're going to get more items on a row obviously it looks terrible right now they're all overlapping but as soon as we make these into cards they're going to perfectly expand and fill the space that we want so let me just bring that back down to a normal size so instead of just rendering out this json version right here we essentially want to render out a component which we're going to call store item and this store item is just going to take in as a prop all of the different item properties name id price image url and so on also for our column we want to give it a key and this key is going to be item.id just like that so now if we just close this off and we save you'll see nothing's quite working that's just because we don't have this store item component yet so instead of our components folder let's create a store item.tsx now this right here is probably going to be one of the more confusing components in our entire stack but the actual html css isn't too bad to do so let's export a function called store item and this is going to take in an id a name a price and an image url just like that and then inside of our store we can make sure we import that store item so let me just save that come over here and we're going to do a quick import of that just like that there we go and now if we go back into our store item here we need to actually give this a type because we're using typescript so we can just say that our type for this is going to be store item props i generally like to just call my prop type whatever my component name is with props at the end of it and this right here is going to be an id which is a number in our case we're gonna have a name which is a string we're gonna have a price which is a number and we're gonna have an image url which is a string so now if we save and we go over to our store hopefully as you can see the error went away that was right here so now we no longer have those errors and inside of here if we just specify this as a store whoops store item props you'll see that all the errors in this file also go away so to create these cards that you can see over here we're going to be using the bootstrap card so we can just come in here we can say we want to return a card from react bootstrap and inside this card we want to do card dot image this is going to give us the image at the top that we care about and we want to say that it's going to be on the top so variant is top we're going to say our source is our image url and then also we want to give it a specified height because all of our images have a different size some are 100 pixels tall some maybe a thousand pixels tall we want them all to be the same size so we're going to come in here with some height we're going to say our height is 200 pixels and then finally the last thing we want to do is also make sure our images are centered so we can do that by saying object fit is center i'm sorry cover and that's just going to make sure our image isn't stretched really weird it's just going to have essentially the right aspect ratio for us if we close off this card image and we save come over to our app you can see now we have four cards and each one just has an image they're all the exact same size and they all are having the correct aspect ratio if i remove this you can see that the aspect ratio is all kinds of messed up but by adding that one line we fix the aspect ratio now let's go back over here to see what we want next thing we want to work on is this title section as well as all the buttons and stuff down here to do that we're going to open up our card dot body and inside of our card body we want to give it a few classes just to do some styling on it we're going to use flexbox inside of here and we want to do a flex column so we're just going to be laying things out using flexbox and we're going to be making them vertically stacked essentially once we've done that we can work on the title next which is just card.title inside of our title we have two sections we have the name here as well as the price and they're spread out as far as possible from each other and the best way to do that again is going to be with flexbox so we can say we want to use flexbox here and we're going to justify our content with space between that's what's going to space them out from each other as far away as possible i also want to align our items on the baseline so that both of our texts have the same bottom point on them that's just going to make it look a little better and then finally i want to give it some margin on the bottom so that our title doesn't touch right up against this add to cart button down here now inside of our title what we need to do is we need to add essentially two spans so two different sections the first section is going to be our title so we can just say name right here i'm also going to increase the font size on that let's just say class name is fs2 and then we need to have another one this is going to be for our price and this price is going to essentially not have a larger size here but what we want to do is we want to add some margin on the left hand side so on the start we want to add a margin of 2 and that's just so if for example this title is really long and it gets really close to this text over here it's not actually going to be touching it there's going to be some space between the two of them also i'm going to give it a class of text muted so that it's actually a little bit of a grayer color instead of having the same text color i say if we go over here you can see we have book and we have our price showing up right there now you will notice they aren't spaced out between each other and that's just because this should say justify content between instead of space between and that's going to fix that problem for us now you will notice one problem though is all of our pricing is not formatted i mean this looks really ugly and we want to format it using like dollar signs commas periods and so on so we're going to create a utility function inside of that utility folder that's going to do all of the formatting for us so instead of utilities we're going to create a new file it's just going to be called the currency format or actually we'll call it format currency dot ts so what we can do is export a function called format currency and this format currency function is just going to take in a number which has the type of number and all we're going to do is return a formatted version and we're going to use the intl formatters for this so we're going to say we're going to create a currency formatter which is equal to a new intl dot number format and this number format is going to have undefined as the locale so it's automatically going to determine how to print out the number based on where you live so if you live in spain or france for example it may print out these numbers differently than if you live in the u.s next what we're going to do is we're going to specify we want the currency to be in u.s dollars and that we want to have the style of this number be a currency number and it's just going to make sure it has the dollar symbol at the front and then it's going to only be two decimal places at the end now to use this formatter we can just come in here say return currencyformatter.format and we pass it in our number that right there is going to format the currency for us so instead of here we can import that function and we can use it right here we can say format currency pass it in our currency just like that and if we make sure it's imported at the top of our page when we save you can now see we get nice formatting with commas you know dollar signs periods where they should be and all that fun stuff now the next section that we need to work on is going to be either the add to cart button or this kind of like plus minus with remove button that you can see here now these are going to determine on if there's anything in the cart already for example if there's no books in the cart show the add to cart button otherwise show this cool thing so it's somewhere inside of here we need to determine what the quantity of items we have is so i'm just going to create a variable called quantity for now this is just a placeholder variable so we can test out the two different versions of the ui one where our quantity is zero and one where our quantity is some other number than zero so we're going to start it out with zero for now so right below our title we're going to create a div we're going to give this a class name here of mt auto and that's just so that this is going to essentially fill all of the space available in that flex container that we have right here we have this flexbox container this is going to fill all the possible space so we have multiple items next to each other for example i expand this you can see that no matter how tall one item is or the other they're all going to fill the exact same height which is exactly what i want now let's bring this back down to a more reasonable size another thing we're going to need to do to make sure that works is we need to come up to our card we need to give it a class name here of h100 so this is going to fill the full height essentially 100 height now inside this margin top auto section that's where we're going to either have our add to cart button or our kind of stylized section up here with the plus and minus buttons so in order to do this we first need to have essentially an if check to see if we are doing this plus or minus version or the add to cart button and to do that we're going to use our quantity so if our quantity is equal to zero then we know that we want to do the add to cart button so if our quantity is zero do an add to cart button otherwise we need to do something else in our case we're just going to render out null for now so let's just put that like this give it a quick save and inside of here we can just do our button so say button like that make sure that we import this button there we go now inside this button we want to say add to cart and now if i save come over here you can see we have this add to cart button but it's obviously not styled like we wanted to so let's add some styles we can say that we want to have our class name be w100 click save and now you can see it's filling the full width which is exactly what we want now next we need to worry about the plus minus with the remove button section now this section is obviously a lot more involved but essentially it's just going to be two flexbox containers this row right here is going to be its own flexbox container and then the whole column is also going to be a flexbox container so we're going to come in here with a div and we're going to give this a class name here of d flex because we want it to be flexbox we're going to align our items in the center and we're going to say flex column and what that is going to do is essentially going to give us a vertical vertical column right here that has everything aligned in the center in the middle just like this and then we also want to add a specific style on here and the style is just going to be a gap of 0.5 rem just to give us some space between these different items now let's close off that div and inside of this div we need to have our other flexbox container which is going to be for this horizontal row so this next horizontal row is going to have a similar class name of d flex and it's going to be aligning the items in the center and we're also going to justify whoops justify our content in the center just to make everything as center aligned as possible and also we're going to give it the same gap so we're going to come in here copy this gap down and paste it in there and we're going to close off the div and for now i'm going to put the text like high inside of this one and i'm going to put the text by inside this one so i come over here and we click or we change our quantity sorry to like one you can now see it says hi and below that it says buy which is exactly what we want now we just need to change high to be some buttons and buy to be our remove button so this section is pretty straightforward actually we need to create a button and this button is going to have a minus symbol in it we also need another button with a plus symbol in it and these buttons essentially are just going to have nothing right now we're going to add some on-click event listeners to them but for now they're just going to be buttons next we want to have a div and this div is going to have a class of fs3 just like that so we can have a larger font and this is going to can change our quantity oops quantity just like that close off that div and actually what i want to do is i'm going to change this to a span and then i'm going to wrap that span in a separate div and inside this other div let me just close it off here i'm going to put some other text so this other text is going to say in cart so now if we save you can see if we come over here it says one in cart and we have a plus and a minus button so that works exactly like we want and the reason i put this in or this one inside of here the quantity inside the span and so i can make the font a little bit larger so it stands out a little bit more now the very next thing we need to do is add another button where this buy goes and we want this to have a variant of danger so it's that red color and this is going to say remove also i want to change the size here to small and now if i save you can see we have that remove button and if we change our quantity up here to zero and we save you can now see it says add to cart now this is giving me essentially an error the reason for that is because we're hard coding our quantity so it's saying like hey your quantity is always zero or your quantity is always one why do you have this if check here but that's going to be changed as soon as we start implementing all of the logic and speaking of logic that's the very next thing that i want to work on so we're going to create a separate context here and this context is going to be called shopping cart context dot tsx on text there we go now inside here i want to have two different functions we export the first one is going to be for getting our context so we're going to export a custom hook called use shopping cart make sure i spell that correctly and this use shopping cart is just going to return calling use context we're going to pass it in our shopping cart context and we need to create this shopping cart context so we can say const shopping cart context is equal to create context which we can import from react and we can pass it in essentially an empty object for now the other function i want to export here is a function for actually implementing the provider portion of this so this provider is going to give me all the values i need and it's also going to do all the code for rendering out our shopping cart when we click on this button over here so we're going to call this shopping cart provider and the shopping cart provider is just going to take in some children and we're just going to re-render out those children and the reason for this is because anytime you use a provider the provider needs to have objects and children inside of it so we're just essentially creating a wrapper around our context that has this children object and then down here we can return our shopping cart context.provider we give it a value which for now we're just going to give it an empty object as our value and then inside of here we're going to render out those children super straightforward and if i save you can see that that is all working we just have an error right here because we need to change the props for this so i'm going to come in here with a type i'm going to call this shopping cart provider props and this is going to have one prop which is children which is just going to be a react node let's make sure we implement that or i'm sorry import that and react node is essentially just like the type that you give to the children property inside of react and now we can just say that this is going to be our shopping cart provider props i like to have all my types at the start of my file so i'm going to move this type up here there we go and now that got rid of all those errors for this and we can actually use this shopping cart provider so if we go into our app we can wrap our entire app inside of our shopping cart provider just like this and if we import this there we go now our entire app has access to all the things inside of our shopping cart provider value inside this context here and if you're kind of unfamiliar with how context works this intersection is going to be really confusing so i highly recommend you check out my completely free react hooks course it's going to be linked in the description for you it'll explain exactly how context works but moving on from that we now need to actually give our context a value besides an empty object now the first thing i want to do is think about what do we all need inside of it so we can create a type for this we're going to call it shopping cart context and inside this type what do we want to do well we need to be able to add things to the cart we need to be able to increment them decrement them and remove them so that's kind of like the main things we need to do and we also need to figure out like how many of an item are in our cart as well so we need different functions for that for example we can do one for getting the item quantity we could say quantity just like that and this will just take in an id which is a number so the id of the item we want and we're going to return a number which is the number of that item we have in our shopping cart now we're going to have a couple other functions for example we want to be able to increase our cart quantity just like that again we're going to be passing in an id and this doesn't return anything we want to have the same exact thing but for decrease we're going to decrease this it's going to take in a id and it's going to return nothing and then finally we're going to do remove from cart which takes in an id and returns nothing so we have four functions and all four of these functions are all the implementation we need to do this store item now you will crucially notice i don't have an add to cart function inside of here and that's because adding an item to the cart is the exact same as increasing our cart quantity by one because going from zero to one is the same thing as adding an item to our cart so i didn't see the need for adding that in now what we can do is we can say that our context is going to be as this type so what this is saying right here is our shopping cart context contains these values as its type so now down here you can see it's saying hey we're missing all those things we need to put increased cart quantity decreased cart quantity removed from cart and so on we need to create those functions now in order to create those functions we obviously need to have a place to store all of our cart information and for now we're just going to do that in a used state but we're going to move this to our own custom hook for local state storage as well so we can say const cart items and set cart items is equal to use state and this use state here is just going to have an empty array by default and we're also going to give this a type of cart item array so let's define that cart item type all the way up here type is a cart item in our case a type for cart item is really straightforward we have an id and we have a quantity oops quantity and both of those are numbers that's all that our cart contains information on and we don't need any more information than that because if we have the id we can look up all the information for like title and price and so on and if we have the quantity we can calculate what the total price is going to be by using the price multiplied by the quantity so that's all we really need to store if we store like the name for example in here as well that's going to be duplicated information and if for example our book name here changes in the future it's not going to line up with the cart item but if we use ids it's going to make sure if we change the book name in our data it's going to get corresponded into this cart item as well so now with that we essentially have a storage place for our cart items now all we need to do is actually create those functions that are going to increment decrement and so on those different values now the first one i'm going to create is going to be the get item quantity because this is pretty easy takes in an id which is a number and inside of this function all i want to do is take our current cart items i want to find the item with the current id so we can say item where the item dot id is equal to our id and then if we have that value i want to return our quantity otherwise i want to return a default value of 0. so with this question mark syntax right here we're saying if this evaluates to something then get the quantity on it or return 0 if we have nothing that's all this function does and we can add that down here into our value so now we have one of those four functions defined next up let's define our increase cart quantity takes in an id which is a number and this function right here is going to be quite a bit more confusing first we just need to call the set cart items i want to get our current items just like that and this current items is going to be whatever our current list of items is and we need to modify this list so if our current items dot find of our item ids are equal so if we can find an item inside of our cart then obviously then that means that we have an item so what we want to do is we want to check to see if we don't have an item because if our item doesn't already exist in the cart well we need to add it to our cart so here we can do is we can just return all of our current items we can add in a new item which has an id and a quantity here quantity of one so this first scenario that we ran into with this if is essentially saying hey you know what if we don't have this item at all stored anywhere then what we need to do is we need to add a new item for it otherwise if the item exists all we need to do is increment the count of that item by one so inside of our else down here we can do a different return and this return is just going to map over all of our current items so we can say map each one of our items and for each one of our items if our item.id is equal to our id then that one we need to change so we can return that item spread it out but we're going to take the quantity and add one to it all we're doing here is saying hey if we found our item take the current item keep everything the same but increment the quantity by one otherwise we're just going to return the item as is without any changes at all so that right there is our increase card quantity done let's add that to our list and slowly and surely these errors are going to get less and less now let's just minimize these both down because the next thing i want to work on is decrease and decrease is somewhat similar to increase the only difference is what i want to do up here in our find is i want to check to see if our quantity is equal to 1. make sure i do this correctly there we go so if the quantity of the item that we find is one well then get rid of it so what we want to do is we want to take our current items and i want to filter them for our item where the id is not equal to our current id and this is just going to return a brand new list of all of our items all of them are going to be exactly the same but whichever one we pass the id of we're going to remove that from our list of items and if we pass an id for an item that doesn't exist this is still just going to return us the current list so it doesn't matter if we pass an id that doesn't exist or we pass an id of something that has a quantity of 1 both of these scenarios are going to work just fine now down here this second part is going to be really straightforward all we need to do is change the plus to a minus and that now takes care of decrease let's minimize that add it into our list decrease card quantity and now we're down to our final function which is remove from cart which takes an id which is a number now this removed from cart is very straightforward essentially all we're going to do is just take this line right here so we can take set cart items get in our current items and all we want to do is just filter out the items where the id is not equal to our current item id that's all that removed from cart is going to do if we save you can now see all the errors in this file are gone and we now have all these values for get item quantity increase decrease and remove so we can use those inside of our actual store item so we can actually use that context so what i want to do is i want to come in here and i'm going to say const git item quantity and let's just say use shopping cart i believe is what i call it there we go we want to get our item quantity we want to get our increase our decrease and our remove function we're going to get all those out of here and then what i want to do is i get our quantity which is just get item quantity for our id so right here we now have our quantity being dynamically set which is perfect and we have the ability to increase decrease and remove our items so let's just set up our event listeners so if we scroll down here we have our button for our add to cart so inside of our add to cart i want to add an event listener for on click and this on click is just going to call the increment function so let's just say increment i'm sorry it's increase not increment increase card quantity and we pass it in our id i'm going to do the same thing for a lot of the other sections so we're going to copy this our plus button is doing exactly that so let's just paste it down our minus button is going to be decreasing and our button here for remove is just going to say remove from cart so now let's go ahead and test this we're going to come over here we're going to click add to cart and you can see it added this i click plus it's increasing minus is decreasing if i minus all the way off it gets rid of it click remove it gets rid of it so this is doing exactly what we want now we just need to make it actually show up on our shopping cart right now our shopping cart does nothing and it always says we have three items so now we're going to be working on opening and closing this shopping cart right here also we can actually get this quantity section here as well that's going to be pretty easy to do so if we go all the way back here to where we have our nav bar inside of our nav bar we need to essentially have some functions for opening our cart and we need to have a function for actually giving the quantity of the items inside of our cart inside of our shopping cart context we need to add some functions for that we're going to add here an open cart function which is just an empty function that takes nothing and returns void we also while we're at it probably want to have a closed cart function as well and then we also want to be able to get our cart whoops cart quantity there we go our cart quantity is just a number that's just the total number items in our cart let's move that down here and i also want to get our cart items which is just our cart item array this is all the information we're going to need our cart items are going to be for populating our cart so up here we can put all the information for our cart and the quantity is going to be for our actual button right here same thing with open and close so if we scroll down obviously we don't have those values so we need to work on getting those values let me minimize these functions here them a little closer together whoops there we go that way they're kind of out of our way and what i want to do is first we can just add our cart items in there that's the easiest one to take care so we have our cart items done now the next thing that i want to do is i want to work on our cart quantity so we can just say quantity and let's actually just call this cart quantity this is going to be equal to our cart items dot reduce for each one of them i want to take our quantity and our actual item so this quantity right here is like essentially our total i'm just going to return item.quantity plus our quantity and i'm going to default this to start at 0. so all this is doing is just counting up all the different item quantities for every item in our cart and it's going to return to us this cart quantity variable which we can just paste down here now all we have left is our open and our close functions that need to be implemented to do this we can create a state variable up here this state variable is going to be a very simple state variable that's just going to be defaulted to false i'm going to say is open and set is open and then we're going to have a simple function open cart oops equals set is open to true make sure i spell const correctly and we're going to have closed cart which is going to set our open to false and then down here we can put open cart and close cart and if we save hopefully that should get rid of all of our errors because now we have all of our different values that we need to find so now we can actually move over to our navbar at the very top we can get those values that we want for example our opencart function and our cart quantity we can get those from i'm sorry not from we can get that from the use shopping art there we go now we can put this open cart function when we click on our button we can just say on click is equal to that open cart function and then down here little ways we can put our cart quantity and actually i'm going to move this right here so it actually wraps our entire button because there's no point in having the button be able to open our cart if there's nothing in our cart so now this cart button doesn't even show up until we add something to it and now we have that button here and when i click it it's calling this open cart function but this function doesn't do anything yet so now we need to work on actually styling out how our shopping cart is going to look so inside of our shopping cart context what we want to do is we want to render a section for our shopping cart just like this and we're going to create a brand new component for that called shopping art dot tsx inside here we're just going to export a function called shopping cart and for now we don't know what it's going to take or what it's going to need but we can actually style out the html of it so we can figure out what we need come in here we'll do a quick return we're going to use something called off canvas this is something from bootstrap and that essentially is this like slide in effect that you see right here that's what this off canvas is this off canvas inside of it we need to have an off canvas header and this off canvas header is just going to say cart for example also inside of here we want to give this a close button and we want to make sure that we also say off canvas.title and we'll put our cart text inside of our title if we say that you can see we have our header and then we have our title inside the header and the header has a close button and we can just set the open property of this to true and now if we save and we make sure we import this right here we should see that we have this open on the right hand side of our page or at least open our page somewhere but it doesn't look like it's rendering on our page at all the reason for it is this should say show instead of open now you can see this is showing up on the left side of our page to get it to show up on the right hand side of our page we can say placement is equal to end and now you can see that that's showing up on the right hand side of our page just like we want if we click outside of it it should close it but we don't have an on close event set up to this so we need to set up an on hide event which in our case is called the cart close this cart close function comes from our context so we can import our context here so we can say cart close equals use shopping cart just like that and now we just refresh this real quick we click outside of here it should close but of course this is not working that's because i called this closed cart instead of cart close paste that in here refresh this and now when i click on the outside of it or click on the x here it should close but it's still not closing the reason for this is show was always set to true this should be set to is open whoops is open this is open we can pass into our shopping cart so we can just say is open just like that so this is open will be passed in from here where we just say is open is equal to is open and then inside of here we want to make sure we give this a type so we can say type shopping cart props type or i'm sorry it's going to be is open is a boolean there we go now we refresh by default it's not open if we click this button it's now open click outside of it it closes that's great also we should just make sure we give this the shopping cart props and the next thing i want to do is style out the section of content that goes inside of our card because right here you can see we have our nice little cart items section so to do that we're going to be needing a body so off canvas dot body and inside of the body we're going to create a stack and a stack is just a really easy way to stack things either vertically or horizontally and we can give it a nice gap for example of three to give us some space between each one of our items and this comes from bootstrap up here so inside of this stack what we want to do is we want to loop through all of our cart items our cart items comes here from this so we can say cart items that's part of our shopping cart context so for each one of these we're going to loop through them we're going to get an item and then for each one of those items i want to return a component called a cart item we're going to give it a key of our item dot id and then we're just going to spread out our entire item outside of that cart there we go make sure i close that off add that in and there we go now we just need to create this cart item component so let's come in here cart item.tsx export function cart item and this cart item just takes in one of our items from our cart and our items from our cart have an id and a quantity so that's all we need to care about we can come up here part item props id number quantity number and then here cart item props there we go now inside of here what we need to do is we need to actually implement all of our features so if we look here you can see we're showing the image we're saying the actual price let's add a few more of those to the card i'm sorry the name right here we're saying how many we have in the cart and we're saying the price the total price as well as a remove button that will remove it so we'll just add a couple more of those back to the cart if we have multiple you can see they're showing up just like this so the first thing we need is obviously that remove function so we're going to say remove from cart that is equal to use shopping cart also we need to get our item itself because right now we have the id and the quantity but we don't have like the name price and so on so to get our item we can get that from our store items and the store items is just our json so we're going to import store items from dot dot slash data slash i think it's items yep items.json so what we can do is we can try to find the item that has the id equal to our id and if our item equals null then we're just going to return null essentially we don't want to return anything at all so if we don't have an item we can't find one just return nothing that means item doesn't exist then the next thing we can do is we can come down here and we can turn information about what we actually want to render and we want to render is a horizontal stack so we can come in here say stack and our direction is horizontal and we want to give it a gap of 2. now inside this gap we're going to have a bunch of sections for our image this section right here which is like a vertical stack and then the section over here on the far right so first let's worry about our image so we can say our image here oops make sure that's self-closing we can give it a source which is our item dot image source our image url and we give it some style to make sure the image isn't too large for example our width is 125 pixels height is going to be 75 pixels and then finally object fit is going to be covered there we go give that a quick save real quick and now we can see if we come over to here we refresh this hopefully we add some items to our cart we have some errors showing up let's see what this error is if we inspect real quick go over to our console cart item is not defined and we can see that right here obviously we need to import cart item now hopefully if we just refresh this add some item to our cart it's still not working oh i forgot to save the file that would easily explain it now we can add some items let's add a couple of these open this up and you can see we have the images showing up which is great now adding back into our cart item i want to add a few classes to this stack just to make everything line up a little bit better we're going to change it to be flex we're going to align our items in the center just like that just so everything is going to be center aligned and then the next thing we're going to work on if we come over here we can kind of see is we're going to work on this vertical stack right here so we're going to give it a class name of me auto that's just going to push everything to the far right hand side which is exactly what we want and then we're going to have another div inside of that that's going to be for organizing our different sections so this first div right here is for our item name so we can just say item.name and then also what we want to do is we want to have a span that comes after this so this span that comes after is going to be a text of muted so we're going to say class name text muted and we only want this span to render if we have a quantity above one so if our quantity is greater than one then show this span and inside of here i want to have our quantity with an x after it just like that also i want to change our font size to be a little bit smaller so we're going to say style font size and this font size is 0.65 rem and let's just make sure all this is showing up correctly it looks like i'm probably missing right there now if i save you can see everything's rendering correctly come over here give it a quick refresh add some items to our cart come over here you can see it says 2x this should say x2 instead of 2x but other than that it looks like it's working exactly as we want it to so we can move on to the next section which is rendering out this pricing section down below and that's going to be in another div that comes after first of all i want to give it that same muted text and i want to change the style of the font size again to be a little bit smaller so we'll say 0.75 rem and then i want to essentially just format our currency so we can say format currency of our item price just so it looks a little bit nicer when we actually render this out give that a quick save refresh over here add an item to the card come over here you can see it renders out the price next we just need to add the total price as well as this x button on the right the total price is super straightforward i'm just going to copy this format currency so we're going to create a div and inside that div we're going to format the currency of our price times our quantity super straightforward and we might as well just do the remove button while we're at it so it's coming here with a button variant is going to be outline danger size is going to be small and on click we just want to call that remove function we can say remove from cart item dot id and this will just say ampersand times that will give us that x button let's make sure we import that and now if we save and we refresh this we'll just add a couple items to our cart come over here and now you can see everything is showing up we click the x button and it removes those items from the cart now the very last thing we have to implement is our total section as you can see over here we have a total but that's not in one of our cart items that's all the way back in our shopping cart now our total we want to put inside of our stack so we're going to create a div for it we're going to give it a class name here which margin start of auto that's going to push our total as far to the right as possible we also wanted to have bold font and we want it to have a larger font size now inside this div we just want to say the text total and then we obviously want to format our currency so we're going to format our currency and this is going to take our cart items and we want to reduce this down to a single value so we're going to take our total and our current cart item just like this and inside of here what i want to do is i want to get our item and that item is going to be coming from our store item just like we did inside of here so i can actually just kind of copy this code i'm just going to paste it down here we're going to take in our cart item dot id and i'm going to take that import for our store items i'm just going to paste it at the top here just like that so now we're getting our individual item from our store items and then what i want to do is try to return the total plus our item.price times our cart item dot quantity and our items sometimes will not exist so in order to take into account when our item doesn't exist we can just say item price and by default we're just going to set it to zero just like that the final thing we needed to do is we just need to make it so that we default our initial counting to zero and that should hopefully solve all the problems that we need now if we come over to our app let's just add a couple of these gonna come in maybe we'll add a couple of these add one of these we come over to our cart and now you can see our total is just the accumulation of all three of those different numbers and if i remove something you can see our total changes now that's almost everything for our shopping cart the last thing we have left is to make it so that when we refresh our page all the items in our cart stay there because they currently do not this is really easy to do we're going to create a custom hook called use local storage dot ts and then inside of our shopping cart context we're just going to use that local storage so up here instead of use state we're going to use local storage and this used local storage is going to take in another property and this property is going to be the default value we can just call it like shopping cart for example it doesn't really matter what you call it and then we can make this hook so export function use local storage just like that and then we can import that into here there we go that should fix most of those errors now what we need to do with our used local storage hook is we need to make it so that it works with custom generic types as well as these different props so if we come over to that hook real quick we of course need to make it a generic so we're going to say t right here that's going to be our generic type and we're also going to say that it's going to have a key which is a string and it's going to have initial value and the initial value is either going to be a type of t or it's going to be a function that returns this type of t and this type of t is just whatever we pass here for our used local storage hook so we said it's an array of cart items that's all that this right here is saying with our used local storage hook that's what this t represents it can be any type you want we're just saying whatever type it is this initial value is either going to be that type or a function that returns that type that's it now we need to do is we need to actually implement our use state logic so we can come in here and we can say we're going to get a value and a set value which is going to be equal to u state and this u state right here is going to be of this generic type t and what we want to do is we want to use the function version of it because we only ever want to invoke checking our local storage one time because it's kind of a slow operation to do and we don't want to do this every time our component re-renders so here we get our json value which is just localstorage.getitem of our key and then if our json value is not equal to null well that means that we have value stored in our local storage so we want to just parse that out so we're going to just json parse our json value and we're going to return that just like that and that right there is going to get us this value right here that we care about the next thing we need to do is check what happens if we don't have that so if we don't have that then that needs we need to check the type of our initial value so if our initial value is a type of function well that means that we need to invoke it as a function so we can return invoking our initial value as a function otherwise we could just return our initial value now we will get one typescript error here essentially saying our types don't line up what we need to do is we need to explicitly tell typescript that this initial value is a type of this invocable function that returns our type of t right here this is just to get around some typescript issues because it thinks that possibly this value right here of t could be a function but we know for a fact it can't be so that just fixes those issues now this just essentially all it does is it gets the value from local storage or it's going to get the initial value that we passed in that's all that code did now the next thing we need to do is we need to set up a use effect that runs every single time our key or our value changes we just want to store our value back in local storage so we can do a set item with our key and we can just stringify our value and then down here we can return value and set value but if we just do that it's actually going to give us an error if you come over here you can see that these values have both an array of card items and it's going to be a set state so of course down here when we try to use these it's going to give us an error to get around this issue it's super simple we just need to explicitly tell it that this is going to be an array with t and it's going to be an array which is just value i'm sorry type of set value we can even do the same thing here we just say type of value and that's just saying that the first element in our array is always going to have this type right here and the second element is always going to be this type now when we go back into here we hover this you can see this is always an array of card items and this one right here is always this like react set state thing so now with that done if we add some items to our cart and let's just come in here we'll add a couple of these add a couple of those you can see we have two books three computers if i refresh my page you can see we still have two books and three computers if i get rid of one of them refresh come back you can now see we still just have those two books now if you enjoyed this project you're definitely going to love my full react course it's going to be linked down in the description below and if you're not ready to pay for a course you can also check out my free react hooks course it's also going to be linked down in the description below with that said thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 232,247
Rating: undefined out of 5
Keywords: webdevsimplified, shopping cart js, shopping cart, shopping cart react js, shopping cart react, shopping cart react javascript, react js, react, javascript react, react ts, react typescript, shopping cart typescript, ts shopping cart
Id: lATafp15HWA
Channel Id: undefined
Length: 61min 38sec (3698 seconds)
Published: Tue Jun 21 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.