How to create websites like shopping cart in React.

  1. useState -which makes the work painless for creating the interactive UI designs. It means you want to create views in such a way that which takes input from user & according to the input in makes changes in UI. In react we can define state in view application & react will update the value as per user changes(inputs) and it will also render the updated value in right components.
  2. Components-create small components with their functionalities & states then compose them for building big complex application. Components can get data from parameters passed via app(parent components).
  3. Create once use anywhere-Here you can create individual components & export them so that they can be imported in other components wherever required. If we want to make any changes in application, then instead of making changes in all components we can just go to that particular component & make required changes. It will automatically get updated wherever it is imported & used. So as in JS if we want navigation bar in all pages we have to copy paste same<nav> element in all pages. And if we want to make any changes in that nav ,then we have to update it in all pages separately. But using react we create separate nav component and just make the changes in that particular nav. Now wherever it is used or imported by using <nav /> react tag ,it will get updated. In react without rewriting the code you can add new features. It makes the work more easier.
import "./styles.css";import AdderSubtractor from "./AdderSubtractor.js";import book_Image from "./Images/book-Image.png";export default function Item(param) {var ItemparentPlusHandler = param.onPlus;return (<div className="Item">{/* define class name to return div to assign styles in css file */}<div id="Item-div"><span>{param.ItemData.itemName}</span><img src={book_Image} alt="book"></img><h2>{param.ItemData.price}</h2><AdderSubtractoronPlus={ItemparentPlusHandler}onMinus={param.onMinus}/></div></div>);}
import "./styles.css";
export default function App() {return (<div className="App"><h1>Welcome to parent Component</h1></div>);}
  • After creating the App.js file I have focused on the items which I want to show on website. For example I took the book image & created one Images folder in src path where the other App.js files all are present .Then inserted that book image in that folder so later I can use from there.
  • I wanted to create one item having book image and below that there will buttons like ‘+’ which adds that item to cart ‘-’which removes that item from the cart.in between those buttons there will be space which displays the number of times items added or removed.
  • So for this firstly I have created AdderSubtractor.js component. Then added plus,minus buttons & span tag for displaying counts in HTML part in return(). And added logic in JS part of function for counting the clicks. I have added two handlers one for plus button handler another for minus button handler.
  • I wanted to show the count of items selected in DOM. If I use normal variable then it won’t show updated data in DOM. Hence in this case we have to use the useState which works as variable but the difference is that if it set to some other value the react will update that particular component in DOM . So we define it & initialize to zero as below: var[count, setcount] = useState(0);
  • Here initially the count is zero if I click on + button the PlusHandler() will be called. Then it will take the current value in another variable because we can’t directly apply any operation on state variable .So took that state variable in another temp variable then performed increment after incrementing by one set the state variable to new count value. Whenevr setstate starts it will send request to browser to updated new value 7 wait for response. Till it get response next statement get execute hence don’t apply any process directly on state variables. When it get the response immediately it will update that value from DOM.
  • If user clicks on — button same as addition it calls MinusHandler() which decrements the state count by one but it has some exceptions. Initially the count is zero so if user clicks on minus button it should not decrement . Otherwise the count value can go to minus which is not valid. Hence at first we check whether the current value is zero? if zero then directly come out of function. No need to change any state. If it not zero then decrement the count & set it to new value.
  • Refer below code for AdderSubtractor.js component:
import { useState } from "react";import "./styles.css";export default function AdderSubtractor(){var [count, setcount] = useState(0);function PlusHandler() {var temp = count;temp = temp + 1;setcount(temp);}function MinusHandler() {var temp=count;if(temp==0) return;temp--;setcount(temp);}
return (<div><button onClick={PlusHandler}>+</button><span> {count} </span><button onClick={MinusHandler}>-</button></div>);}
  • Now I have created the Item.js component which will be consisting of image of item want to show & will add the previously created AdderSubtractor below this image. Here first I have imported image file from another folder & used in render part in {} brackets. Second thing is imported the AdderSubtractor.js file with it correct path & used in render as <AdderSubtractor /> after image tag.
  • Refer below code for Item.js component:
import "./styles.css";import AdderSubtractor from "./AdderSubtractor.js";import book_Image from "./Images/book-Image.png";export default function Item() {return (<div className="Item">{/* define class name to return div to assign styles in css file */}<div id="Item-div"><img src={book_Image} alt="book"></img><AdderSubtractor/></div></div>);}
  • Now I have one item with image & buttons below. I want to show different items same as this one item. As of now I have decided to use same image to show in all item lists. For this one thing is clear that I will use the item component & using this will create the item list. Here I have used one empty array & pushed the item from Item.js. But to limit the array I have taken param from the parent component App.js & used that in for loop as array length. Here to show the list in view I have used that array in ul tag in html part. If I use only array it will display the items one below one which I don’t wanted.<ul> it will show item one after another in horizontal way after applying some css .
  • Refer below code for ListOfItems.js component:
import "./styles.css";import Item from "./Item.js";export default function ListOfItems(param) {var lengthOfList = param.length;
{/* we can define these param to some variables or can directly use as param.length as the param is object & passed value from parent is in key value form[object.key or object[key]]*/}
var indents = [];for (var i = 0; i < lengthOfList; i++) {indents.push(<Item />);}return (<div><ul style={{ display: "flex", listStyle: "none" }}>{indents}</ul></div>);}
  • Now I have created navbar.js component to just make the website more accessible& attractive. As of now I have just added some dummy data. What I wanted to show is it will consist of navigation bar which show a list after clicking it will navigate to that particular page. Later I will updated this with the new changes. It consist of logic written in js part of functions& View part which we want to show is written in return()html part.
  • Refer below code for Navbar.js component:
import "./styles.css";export default function Navbar() {return (<div className="Main-navbar"><h1 style={{ display: "inline" }}>Shopping cart</h1><ul><li>Electronics</li><li>Mens wear</li><li>Womens wear</li><li>Books</li><li>Fasion</li></ul></div>);}
  • Now I want to show the total number of items selected in my cart in main view page. I have used one image to show as cart & above that another h1 tag used to display count. For this I have created Cart.js component which will take the total calculated count as param from the parent. It’s work is to just display that count in view.
  • Refer below code for Cart.js component:
import "./styles.css";import CartImage from "./Images/CartImage.png";export default function Cart(param) {var { count } = param;return (<div className="Cart-div"><h2>{count}</h2><div><img src={CartImage} alt="cart"></img></div></div>);}
  • Till now I have created all required child components which are the small different parts of main application. Now this was the time to compose all components which I wanted to show in view for user. For this I have to import the child components in App.js. I was clear about the structure that I wanted to show , navigation bar at top of the page & cart at right top corner . Below that I wanted to show the items list. Till this part I was able to write the code in App.js .
  • But the challenge which I was facing here is Cart totalcount. I need the cart value should get changed when I click on the item +,- buttons. It is clear that I have to use useState for updating the total count. But how can I take the count values from the different items , then will add all those and at last show them in parent component.
  • Then I got to know about the binding ways between parent to child & child to parent in react . With help of this I tried to access the datas:
  • Refer below code for App.js component:
import "./styles.css";import ListOfItems from "./ListOfItems.js";import Cart from "./cart.js";import Navbar from "./Navbar.js";import { useState } from "react";export default function App() {var [TotalCount, setTotalCount] = useState(0);function CartPlusHandler() {var temp = TotalCount;temp = temp + 1;setTotalCount(temp);}function CartMinusHandler() {// var k = CartPlusHandler();var temp = TotalCount;temp = temp - 1;// var k = setTotalCount(temp);setTotalCount(temp);}return (<div className="App"><Cart count={TotalCount} /><Navbar /><div><ListOfItemslength="4"CartPlusHandler={CartPlusHandler}CartMinusHandler={CartMinusHandler}/></div></div>);}
  • here in above code parent will pass CartPlusHandler, CartMinusHandler as parameters to the listOfItems child component. So these function definations will sent to listOfItems then from there it it passed to Item from there it is passed to AdderSubtractor . In this way from parent to child to child chain these function definations are passed. In adderSubtractor child, we have already defined functions for plus,minus handler . As soon as it set the count in plus,minus handler it will call the parent functions CartPlusHandler, CartMinusHandler defination. So immediately the particular parent handler starts running the function & it set the total count accordingly.
  • Please keep in mind that I have just passed the function defination (CartPlusHandler, CartMinusHandler)as parameter but not calling that function as (CartPlusHandler(), CartMinusHandler()). If functions are called then it will keep the return value of those functions where it is called.
  • Till now what I have done is : Now I am able to see the navbar at top of the website. At top right corner there is a cart showing the number of items selected. Below this I have list of items showing. In each item there is one image & below that the adder subtractor sign is showing. When I click on those signs it will display the count in those particular item space & also will update the cart Total selected items counts.
  • Till now I have used one fix image only in item part. Now I want to give the names & prices to those items in the item list.
  • Now the challenge I got here is how to give different names & prices to those items as I have just pushed the fix item component in one empty array and showing the array in list of items.
  • This can be done by using mock data. Mock data are nothing but the few list of items which we want to show. Here we can create one separate component consisting of these mock datas stored as objects in array form. Refer below for mockdata used:
export var items = [{itemName: "Book",price: 500},{itemName: "Desk",price: 20000},{itemName: "Watch",price: 2500}
];
  • Now I want these datas should be written in item section. If I directly write the name&price in item component it will show same name for all other items also. It is called static data. If I want to change these according to the mock data then I have to pass some parameter here in items. And also those param should be of that particular indexed item. For example if it is 1st item then it should be book if 2nd then it should be desk. This can be done by accessing the mock datas given in array by thier indexes.
  • In Item component we can just write elements tags for writing names&prices. But the list of items we are getting is from listOfItems components. So here if we pass which name&price should be written to item in for loop to item tag then it will pass those to item& Item will directly use that param in name&price elements.
  • for doing this I have created the mock data as shown above. Imported this in App as I wanted to pass this array as param to listOfItem →Item. Refer below code to know how I passed in App:
<div>{/* <AdderSubtractor onClick={CartPlusHandler}/> */}<ListOfItemsItemList={items}length={items.length}CartPlusHandler={CartPlusHandler}CartMinusHandler={CartMinusHandler}/></div>
  • These param passed to list of items . So in list those params passed to items as below:
import "./styles.css";import Item from "./Item.js";
export default function ListOfItems(param) {var lengthOfList = param.length;var ListparentPlusHandler = param.CartPlusHandler;var indents = [];for (var i = 0; i < lengthOfList; i++) {indents.push(// {items[i].itemName},<ItemItemListsData={param.ItemList[i]}onPlus={ListparentPlusHandler}onMinus={param.CartMinusHandler}/>);}return (<div><ul style={{ display: "flex", listStyle: "none" }}>{indents}</ul></div>);}
  • Now in Item components changes are made as below: Here it will just give the element tags where name&price should be seen on screen.
import "./styles.css";import AdderSubtractor from "./AdderSubtractor.js";import book_Image from "./Images/book-Image.png";export default function Item(param) {var ItemparentPlusHandler = param.onPlus;return (<div className="Item">{/* define class name to return div to assign styles in css file */}<div id="Item-div"><h3>{param.ItemListsData.itemName}</h3><img src={book_Image} alt="book"></img><h3>Rs.{param.ItemListsData.price}</h3><AdderSubtractoronPlus={ItemparentPlusHandler}onMinus={param.onMinus}/></div></div>);}
  • After this change ,I wanted to show the selected items bill & total bill needs to pay. So for this as first step I have decided to use mock data like above for showing chosen items Name,quantity,price.And this array is created in same component which is showing name,price array.These data also stored as objects in array form only as shown below:
export var ChosenItems = [{itemName: "Book",count: 5,price: 500},{itemName: "Desk",count: 1,price: 20000},{itemName: "Watch",count: 2,price: 2500}];
  • To use this above array firstly I have created one separate component as ItemBill consisting of html structure for showing items bill section. Here also I don’t wanted to write all items statically. Hence I have passed this above array as param to the ItemBill component. This ItemBill is displayed in App itself only after the list part. In this ItemBillI I have used one for loop for taking all chosen items data from the array written above. Then accessed the passed params to show items details & used html table elements in array to show in structured formats.
  • Used add function to for calculating the grandTotal of all items price.
export default function ItemBill(param) {var SelectedItems = [];var sum = 0;for (var i = 0; i < param.Itemlist.length; i++) {SelectedItems.push(<tr><td>{param.Itemlist[i].itemName}</td><td>{param.Itemlist[i].count}</td><td>{param.Itemlist[i].price}</td><td>{param.Itemlist[i].price * param.Itemlist[i].count}</td></tr>);}function Add() {for (var i = 0; i < param.Itemlist.length; i++) {sum = sum + param.Itemlist[i].price * param.Itemlist[i].count;}return sum;}return (<div className="MainBill"><table><tr><th>Item</th><th>Quantity</th><th>Price</th><th>TotalPrice</th></tr>{SelectedItems}<tr><th>GrandTotal</th><td>Rs. {Add()}</td></tr></table></div>);}
  • In this way we can use generic data in our application. Because it will make the code more understandable & reusable. Here anyone can use the components by just changing the items details whatever they want. So always try to think in this way that if someone wanted to use my created components but want to change some data is it possible with this code or not?
  • Use generic code over static. Use static for just creating structure at first step then remove those & use generic data.
  • Learn more about using for loops,how to push items in array,functions,how to call functions,how to just pass function definations,how to write array,objects,how to access them,how to pass objects as param,how to import,export files,check file path corrcetly,identify the errors cuased & work on it.
for (var i = 0; i < lengthOfList; i++) {indents.push(// {items[i].itemName},<Itemindex={i}ItemListsData={param.ItemList[i]}onPlus={ListparentPlusHandler}onMinus={param.CartMinusHandler}ItemCountHandler={param.CountHandler}/>);}
<AdderSubtractorindex={param.index}onPlus={ItemparentPlusHandler}onMinus={param.onMinus}ASCountHandler={param.ItemCountHandler}/
function PlusHandler() {var temp = count;temp = temp + 1;setcount(temp);param.onPlus();param.ASCountHandler(temp, param.index);}function MinusHandler() {var temp = count;if (temp == 0) {return;}temp--;setcount(temp);param.onMinus();param.ASCountHandler(temp, param.index);}
import "./styles.css";import ListOfItems from "./ListOfItems.js";import Cart from "./cart.js";// import Navbar from "./Navbar.js";import { useState } from "react";import { items } from "./ItemData";import ItemBill from "./ItemBill";import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";export default function App() {var [TotalCount, setTotalCount] = useState(0);var [Quantity, setQuantity] = useState(0);var quantityprivate = 0;var AppChosenItems = items;function CartPlusHandler() {var temp = TotalCount;temp = temp + 1;setTotalCount(temp);}function CartMinusHandler() {var temp = TotalCount;temp = temp - 1;setTotalCount(temp);}function CountHandler(quant, index) {console.log("App got singal to assign value" + quant + " to index" + index);AppChosenItems[index].count = quant;setQuantity(quant);quantityprivate = quant;console.log("Inside count handler" + quant);}return (<div className="App"><Cart count={TotalCount} /><Router><nav><h1>Shopping cart</h1><Link class="link" to="/ListOfItems">{" "}ListOfItems{" "}</Link><Link class="link" to="/ItemBill">{" "}TotalItemBill{" "}</Link></nav><Routes><Routepath="/ListOfItems"element={<ListOfItemsItemList={items}length={items.length}CartPlusHandler={CartPlusHandler}CartMinusHandler={CartMinusHandler}CountHandler={CountHandler}/>}/><Routepath="/ItemBill"element={<ItemBillItemlist={AppChosenItems}Itemlength={AppChosenItems.length}ItemCount={Quantity}/>}/></Routes></Router></div>);}
  • In javascript we create separate html pages of list items to show in nav bar then use <a> tag & insert the path of perticular pages in it.
  • But here we have to write same thing many times & needs to copy paste the nav section ,footer section html part in each page.
  • And another thing is as in JS we have create different html&JS files for each pages/sections for showing in navigation like about.html, about.js,Account.html,Account.js etc like this .
  • But in React we don’t have so many html,js files. Here we use only one main index.html to which the view data is passed through the App.js main parent component.
  • Hence here we just create different .js components & insert the components tags in router elements. & give the path to it as shown in below code.
  • But react make it more easy without rewriting the same code. Here we use browser router elements & Links elements in parent component. We import browser router as router to make it easy,short to write and also import routes,route,Link from react-router-dom. We import these where we wanted to show the navigation bar .
  • Here I wanted to show the nav bar in parent App.js component. Hence added all these required elements as below:
import "./styles.css";import ListOfItems from "./ListOfItems.js";import Cart from "./cart.js";// import Navbar from "./Navbar.js";import { useState } from "react";import { items } from "./ItemData";import ItemBill from "./ItemBill";import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";export default function App() {var [TotalCount, setTotalCount] = useState(0);var [Quantity, setQuantity] = useState(0);var quantityprivate = 0;var AppChosenItems = items;function CartPlusHandler() {var temp = TotalCount;temp = temp + 1;setTotalCount(temp);}
function CartMinusHandler() {var temp = TotalCount;temp = temp - 1;setTotalCount(temp);}function CountHandler(quant, index) {console.log("App got singal to assign value" + quant + " to index" + index);AppChosenItems[index].count = quant;setQuantity(quant);quantityprivate = quant;console.log("Inside count handler" + quant);}return (<div className="App"><Cart count={TotalCount} />{/* <Navbar /> */}<Router><nav><h1>Shopping cart</h1><Link class="link" to="/ListOfItems">{" "}ListOfItems{" "}</Link><Link class="link" to="/ItemBill">{" "}TotalItemBill{" "}</Link></nav><Routes><Routepath="/ListOfItems"element={<ListOfItemsItemList={items}length={items.length}CartPlusHandler={CartPlusHandler}CartMinusHandler={CartMinusHandler}CountHandler={CountHandler}/>}/><Routepath="/ItemBill"element={<ItemBillItemlist={AppChosenItems}Itemlength={AppChosenItems.length}ItemCount={Quantity}/>}/></Routes></Router>{/*<div><ListOfItemsItemList={items}length={items.length}CartPlusHandler={CartPlusHandler}CartMinusHandler={CartMinusHandler}CountHandler={CountHandler}/></div><div><ItemBillItemlist={AppChosenItems}Itemlength={AppChosenItems.length}ItemCount={Quantity}/></div>*/}</div>);}
  • Here in above code I have highlighted the router elements & other required tags which are needed. We fistly import all required elements from library then use those in html code.
  • Everything is written in <Router> →<Link> →<Routes> →<Route>.
  • Here the route will show the according to clicked item from nav bar. But here some one need to change the path then only the router will show the pages . But it won’t change automatically we have to update or add the path in url.
  • But if we use link then after clicking on those items it will change the path in url then the route will show the page as per the path. Here the Link is used to show the list of items availabe to navigate in nav bar just like <a> tag.
  • Then added some styling to keep it in structured & good looking form.
  • Watch few react router related videos to explore & understand the concept clearly.
  1. return is used in functions to return some value. It is not compulsory to use return at last line of the function.
  2. You can use return at any line in but wherever you write return it will come out of that function at that point.
  3. return can used to return some value or just used to come out of that function. If return not mentioned by default it will take return at last line of that function.
  4. you can use if..else or any conditions & after checking conditions you want to return those values you can mention as return value; after that.
  • how state works
import "./styles.css";import ListOfItems from "./ListOfItems.js";import Cart from "./cart.js";import Navbar from "./Navbar.js";import { useState } from "react";import { items } from "./ItemData";import { ChosenItems } from "./ItemData";import ItemBill from "./ItemBill";export default function App() {var [TotalCount, setTotalCount] = useState(0);var [Quantity, setQuantity] = useState(0);var quantityprivate = 0;function CartPlusHandler() {var temp = TotalCount;temp = temp + 1;setTotalCount(temp);}console.log("Refreshing" + JSON.stringify(items[0].itemName));console.log("quantify state" + Quantity);console.log("quantity private" + quantityprivate);function CartMinusHandler() {// var k = CartPlusHandler();var temp = TotalCount;temp = temp - 1;// var k = setTotalCount(temp);setTotalCount(temp);}function CountHandler(quant) {setQuantity(quant);quantityprivate = quant;console.log("Inside count handler" + quant);}return (<div className="App"><Cart count={TotalCount} /><Navbar />{/* <h1 style={{ display: "inline" }}>Welcome to my website</h1> */}{/* <div style={{ display: "inline" }}><Cart /></div> */}<div>{/* <AdderSubtractor onClick={CartPlusHandler}/> */}<ListOfItemsItemList={items}length={items.length}CartPlusHandler={CartPlusHandler}CartMinusHandler={CartMinusHandler}CountHandler={CountHandler}/></div><div><ItemBill Itemlist={ChosenItems} ItemCount={Quantity} /></div></div>);}
  • here when you click on plus it will call CountHandler hen in that function only we are changing state but untill it gets the response below statements will run hence we get the — console part as ->Inside count handler1 Then it get response & state get changes.So when any state get updated it will rerender the component where it is defines hence App will run again from top line by line so it again prints →Refreshing”Book” . But after this it will take the updated state as ->quantify state1.state value remains same as before rerendering but the private,local,static values get initial values again as code started to run from top line.hence shows ->quantity private0
  • If I comment out the setstate line →setQuantity(quant); in function then the output will be as below-
  • output —
  • Inside count handler1
  • Refreshing”Book”
  • quantify state0
  • quantity private0
  • Inside count handler2
  • Refreshing”Book”
  • quantify state0
  • quantity private0
  • Always keep in mind that as we set state values it will req DOM till it get response it will run the next statements which is called async functioning. In this case if you purposely want to wait till getting the response then you can use wait.
  • Another thing to keep in mind that before setting the state value if you want to perform any process like add,sub etc then don’t directly use the state variable. Define local variable and assign initial state value at this time.Then do the process on local/temp variable then setState(tempVariable). It won’t make any conflicts with values in time of getting responses.
  • We can also use the previous state values for not to wait condition.
eg:var [count, setcount]=useState(0);
function Totalcount(){
var temp=count;
temp++;
setcount(temp);
}
OR
var [count, setcount]=useState(0);
function Totalcount(){
var temp=count;
temp++;
setCount((prevcount) => temp);
}
  • Local variable value
  1. In react whatever the variables we define has a important part. If the variables define as local variable then these variable values are reset when the application and the particular component is mounting. Mounting means the whole thing which we can see on screen when we first hit to the website.
  2. When the components are rendering then also these local variables values are reset.
  3. When any part of application is unmounting &then mounting then the local variables values defined in that perticular component will also reset.
  • State variable value
  1. In react most of the time we use state variable whenever we want to rerender the page with upadated values in DOM. Its good practice to State. State variables are reset when the application is mounting.
  2. when the components are rerendering then these state variables won’t reset. These will takes its previous values.
  3. When the application any part unmounting & mounting again then also these state variables won’t reset.

Will update remaing part soon…

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Deepali

Deepali

More from Medium

Plaid Integration in React app

Simple NBA MVP Voter

Using Custom Cursors with Javascript for a Better User Experience

Front-End Development — All you have to know.