O curso definitivo de React 2025 — crie 3 projetos reais | Code Bless You | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

The Ultimate React Course 2025 - Build 3 real-world Projects

teacher avatar Code Bless You, Making Coding Easy To Learn

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      React Masterclass Introduction

      3:26

    • 2.

      What is React?

      7:21

    • 3.

      Setup Development Environment

      3:59

    • 4.

      Creating React Application

      3:26

    • 5.

      Let's understand the React template

      7:41

    • 6.

      Writing Code from Scratch

      3:45

    • 7.

      Section 02 JavaScript ES7 Refresher

      1:00

    • 8.

      var, let and const

      4:20

    • 9.

      Arrow Function

      2:58

    • 10.

      Accessing the objects

      1:46

    • 11.

      Object Destructuring

      3:00

    • 12.

      Map method

      3:48

    • 13.

      Filter Method

      3:19

    • 14.

      Spread Operator

      4:45

    • 15.

      Ternary Operators

      3:10

    • 16.

      Modules in JavaScript

      6:20

    • 17.

      Export as Default

      3:28

    • 18.

      Section 03 React Basic Concepts

      0:45

    • 19.

      Setting up new project

      1:54

    • 20.

      Building own component

      6:39

    • 21.

      Solution of this exercise

      1:15

    • 22.

      How JSX and Babel works

      3:13

    • 23.

      Adding Elements in Components

      3:45

    • 24.

      JavaScript expression in JSX

      4:49

    • 25.

      Setting attributes in elements

      4:25

    • 26.

      Events in React

      3:22

    • 27.

      What is State

      1:43

    • 28.

      Introduction of React Hooks

      1:24

    • 29.

      useState Hook

      6:15

    • 30.

      Handling user inputs

      4:06

    • 31.

      Mapping Lists

      3:31

    • 32.

      Section 04 Creating First Project in React

      0:40

    • 33.

      Project Overview and Planning

      2:48

    • 34.

      Creating the website layout

      5:39

    • 35.

      Creating Task Form Component

      3:41

    • 36.

      Adding styles for form component

      7:18

    • 37.

      Creating Tag Component

      1:59

    • 38.

      Props in React

      4:29

    • 39.

      Building Task List Component

      5:59

    • 40.

      Solution of this exercise

      4:08

    • 41.

      Building TaskCard Component

      7:34

    • 42.

      Section 05 Adding Functionality in Project 1

      0:38

    • 43.

      Handle Form

      5:32

    • 44.

      Shortcut trick to handle form

      8:38

    • 45.

      React Strict Mode

      2:37

    • 46.

      Tag Selection

      7:55

    • 47.

      Display selected tag on UI

      5:44

    • 48.

      Displaying the Task Cards

      7:35

    • 49.

      Deleting Single Task

      6:18

    • 50.

      Basics of useEffect hook

      5:36

    • 51.

      Adding custom fonts

      2:06

    • 52.

      Wrapping up Project 01

      1:06

    • 53.

      [Optional] Drag and Drop feature in React

      21:39

    • 54.

      Section 06 Project 02 - MovieManiac

      0:43

    • 55.

      Setting up project & Layout style

      6:00

    • 56.

      Adding Custom Fonts

      4:35

    • 57.

      Building Navbar Component

      6:56

    • 58.

      Building MovieList Component

      9:37

    • 59.

      Building MovieCard Component

      4:07

    • 60.

      Styling the MovieCard Component

      8:31

    • 61.

      What is an API

      4:04

    • 62.

      Generating the API key

      5:36

    • 63.

      Calling API using Fetch method

      7:31

    • 64.

      Exercise for MovieCard

      0:30

    • 65.

      Solution for this exercise

      5:33

    • 66.

      Section 07 - Filtering, Sorting & Dark Mode Features

      0:24

    • 67.

      Filter vs Sort

      1:08

    • 68.

      Implementing Filter Feature

      7:21

    • 69.

      Creating Resuable Filter Section

      3:52

    • 70.

      Handling Sorting Selection

      4:03

    • 71.

      Debugging React Application

      2:25

    • 72.

      Implementing Sorting Feature

      7:01

    • 73.

      Adding Switch for Dark Light Mode

      4:02

    • 74.

      Dark Mode Implementation

      9:23

    • 75.

      Making MovieList component Reusable

      6:54

    • 76.

      Section 08 React Routing

      0:37

    • 77.

      Setting up Project

      2:27

    • 78.

      Adding Routing for React Application

      7:09

    • 79.

      Adding not found page

      1:32

    • 80.

      Making Single Page Application

      3:49

    • 81.

      Route Parameters (useParams)

      5:33

    • 82.

      Query String

      5:07

    • 83.

      Nested Routing

      5:40

    • 84.

      Programmatically Navigation

      4:02

    • 85.

      Exercise for Routing

      1:31

    • 86.

      Adding Routing to Project 02

      7:28

    • 87.

      Defining Route Parameter for Single Movie

      3:58

    • 88.

      Section 09 Calling an API

      0:40

    • 89.

      useEffect hook in detail

      4:56

    • 90.

      Dependencies of useEffect

      2:44

    • 91.

      useEffect clean up function

      4:03

    • 92.

      Basics of HTTP Requests

      2:37

    • 93.

      Fetching Sellers data

      6:46

    • 94.

      Adding Loading Indicator

      5:14

    • 95.

      Handling Errors

      2:56

    • 96.

      Promise with async await

      2:47

    • 97.

      Adding New Seller

      6:44

    • 98.

      Deleting the Seller

      5:00

    • 99.

      Exercise for calling API

      0:52

    • 100.

      Solution Updating the Seller

      4:12

    • 101.

      Creating axios variable for HTTP Requests

      3:17

    • 102.

      Section 10 - Project 03 E-commerce Application

      2:18

    • 103.

      Setting up Project & layout style

      4:19

    • 104.

      Building Navbar Component

      7:19

    • 105.

      Adding Navbar Links

      9:23

    • 106.

      Building Hero Section

      11:35

    • 107.

      Adding Featured Products Section

      3:41

    • 108.

      Creating Product Card

      11:06

    • 109.

      Building Product Page

      10:02

    • 110.

      Creating Product List Section

      6:00

    • 111.

      Creating Single Product Component

      7:57

    • 112.

      Adding Details Section for Product Page

      7:21

    • 113.

      Building Cart Page Component

      8:11

    • 114.

      Creating Common Table Component

      6:51

    • 115.

      Modifying Cart Page Component

      3:49

    • 116.

      Section 11 Advance Form

      0:31

    • 117.

      Building Login Form

      6:54

    • 118.

      Understanding useRef hook

      5:23

    • 119.

      Handling Form using Ref hook

      4:51

    • 120.

      Handling Form using State hook

      3:05

    • 121.

      Managing form with React Hook Form

      5:20

    • 122.

      Form Validation

      5:14

    • 123.

      Form Validation based on Schema

      7:18

    • 124.

      Exercise for Forms

      1:25

    • 125.

      Solution of this Exercise

      7:47

    • 126.

      Handling Image upload

      4:04

    • 127.

      Section 12 Connection to the Backend

      0:49

    • 128.

      Install MongoDB & Compass in Windows

      4:12

    • 129.

      Setting up backend

      3:18

    • 130.

      Implementing Routing in our Application

      6:02

    • 131.

      Fetching Products

      6:42

    • 132.

      Making Product Card Dynamic

      4:20

    • 133.

      Fetching Categories

      4:09

    • 134.

      Creating Fetching Custom hook

      7:26

    • 135.

      Adding Loading skeleton

      6:35

    • 136.

      Fetching products by category

      5:29

    • 137.

      Pagination

      6:15

    • 138.

      Creating Pagination UI

      11:09

    • 139.

      Infinite Scrolling

      15:01

    • 140.

      Exercise Single Product Page

      1:07

    • 141.

      Solution of this exercise

      7:21

    • 142.

      Section 13 Authentication & Authorization

      0:35

    • 143.

      Register a new user API

      4:51

    • 144.

      Connecting Signup Page with API

      5:56

    • 145.

      Handling Errors for Signup

      2:50

    • 146.

      Login a user API

      1:41

    • 147.

      Connecting Login Page with API

      2:57

    • 148.

      What is JWT & How it works

      5:21

    • 149.

      Storing the JWT after Login & Signup

      3:41

    • 150.

      Getting User from Token

      6:01

    • 151.

      Hide Show Component depending upon User

      3:54

    • 152.

      Implementing Logout Functionality

      2:47

    • 153.

      Simplify the code

      5:51

    • 154.

      Section 14 Calling Protected APIs & Routes

      0:40

    • 155.

      Understanding Add to Cart Feature

      1:46

    • 156.

      Add To Cart Locally

      7:43

    • 157.

      Calling Protected API

      6:02

    • 158.

      Calling Add to Cart API

      7:01

    • 159.

      Fetching User Cart From Backend

      8:59

    • 160.

      useContext hook

      7:11

    • 161.

      Exercise Creating Cart Context

      4:56

    • 162.

      Removing Items From Cart

      4:37

    • 163.

      Increase and decrease product quantity

      6:59

    • 164.

      Add to Cart in Product Card

      4:42

    • 165.

      Calling API for Checkout

      4:18

    • 166.

      Exercise Getting Users Order

      0:24

    • 167.

      Solution for this exercise

      4:13

    • 168.

      Creating Protected Routes

      3:42

    • 169.

      Redirect to previous protected page

      4:52

    • 170.

      Section 15 Fixing Some Issues

      1:08

    • 171.

      Fetching Featured Products

      4:06

    • 172.

      Fetching Products by Search Query

      6:26

    • 173.

      Auto Suggestion in Search bar

      10:03

    • 174.

      Navigation for Auto Suggestion

      7:08

    • 175.

      Debouncing method for getting suggestion

      3:00

    • 176.

      Sorting Product List

      5:12

    • 177.

      Section 16 Performance & Code Management Hooks

      0:34

    • 178.

      Understanding useMemo hook

      6:21

    • 179.

      Exercise for SubTotal

      1:46

    • 180.

      Understanding useCallback hook

      6:27

    • 181.

      How to use useCallback hook in React

      3:59

    • 182.

      Exercise for useCallback hook

      3:43

    • 183.

      useReducer hook

      9:12

    • 184.

      Exercise for Reducer

      0:44

    • 185.

      Complex Actions for Reducer

      9:53

    • 186.

      Section 17 Master React-Query

      1:09

    • 187.

      What is React Query and Why we need it

      2:52

    • 188.

      Setting up React Query in our Project

      2:41

    • 189.

      Fetching Sellers Data

      6:34

    • 190.

      Error Handling & Loading

      1:56

    • 191.

      Creating custom hook with React Query

      1:51

    • 192.

      Adding React Query DevTools

      3:40

    • 193.

      Customize our React Query Properties

      6:09

    • 194.

      Exercise for Fetching Data

      5:11

    • 195.

      Understanding Query Params in React Query

      8:31

    • 196.

      Pagination in React Query

      6:37

    • 197.

      Infinite Scrolling in React Query

      7:40

    • 198.

      useMutation hook for Mutation

      8:08

    • 199.

      Delete and Update Sellers

      5:49

    • 200.

      Handling Error in Mutation

      2:24

    • 201.

      Showing progress during mutations

      1:48

    • 202.

      Optimistic update in React Query

      7:38

    • 203.

      Custom hook for AddSellers Mutation

      2:49

    • 204.

      Section 18 Improving website performance with React Query

      0:59

    • 205.

      Do you really need React Query

      2:33

    • 206.

      Setting up React Query

      3:06

    • 207.

      Fetching Data using useQuery

      8:09

    • 208.

      Implementing Infinite Query

      13:28

    • 209.

      Should we add caching in AutoSuggestions

      1:30

    • 210.

      Updating getCart Query

      2:49

    • 211.

      Mutation for Add to Cart

      9:04

    • 212.

      Mutation for Remove from Cart

      4:29

    • 213.

      Mutation for Increase and decrease

      5:59

    • 214.

      Section 19 Deployment

      0:26

    • 215.

      Beginning of Deployment

      1:22

    • 216.

      Adding MongoDB Cloud

      4:26

    • 217.

      How to upload projects on github

      5:22

    • 218.

      Deploying Backend

      4:29

    • 219.

      Preparing our React application for deployment

      3:58

    • 220.

      Deploying React Application

      5:23

    • 221.

      Thank you!

      0:25

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

44

Students

--

Project

About This Class

Welcome to React Masterclass 2025 course! In this course you will learn React JS from the beginning to building real-world applications with best practices. So whether you are complete beginner or you learn little bit about React, you will learn how to build react applications with ease.

Click here to download resources folder.

During this Course you'll create 3 amazing and real world project with beginners, intermediate and advanced difficulties. Let's see what you will create during this course.

Project 01 - To-Do Application [ Basic Difficulty ]

Project 02 - Movie Listing Application [ Intermediate Difficulty ]

Project 03 - E-commerce Application [ Advanced Difficulty ]

WHAT YOU'LL LEARN:

  • Understand React Basics: Grasp key concepts like components, JSX, props, and state.
  • Create Reusable Components: Build modular and scalable UIs with React.
  • Manage State Effectively: Use hooks like useState and useEffect to handle dynamic data.
  • Handle User Events: Implement event handling for seamless interactivity.
  • Navigate with React Router: Create single-page applications with multi-page functionality.
  • Deploy Your React App: Take your project live with an easy deployment process.

WHO THIS CLASS IS FOR:

  • Beginners: No prior experience with React is needed, but a basic understanding of JavaScript will be helpful.
  • Developers: Experienced coders looking to add React.js to their skillset.
  • Anyone Interested in Modern Web Development: If you want to stay ahead in the tech world, this class is for you!

WHAT YOU'LL NEED:

  • A computer with a modern web browser.
  • Basic familiarity with HTML, CSS, and JavaScript.
  • Node.js installed on your system (we’ll cover setup too!).
  • All necessary starter files and resources will be provided during the class.

Join the class today and take your first step toward becoming a React.js pro. Let’s build amazing web apps together!

WHAT YOU'LL LEARN:

  • What is React.js? (Introduction to React)
  • Setting Up React.js (React Installation Guide)
  • React Components Explained (Functional vs Class Components)
  • React Props Tutorial (How to Use Props in React.js)
  • React State Management Basics (Introduction to State in React)
  • React Lifecycle Methods Overview
  • Understanding React Hooks (useState, useEffect, and more)
  • React Event Handling (How to Handle Events in React.js)
  • JSX in React Explained (JavaScript Syntax for React)
  • React Router Tutorial (Routing in React.js Applications)
  • Single Page Applications with React Router
  • React Router DOM Basics (Navigate Between Pages in React)
  • React Form Validation Tutorial
  • Handling Input Fields in React.js (Controlled vs Uncontrolled Components)
  • File Upload in React.js (Step-by-Step Guide)
  • Fetch API in React (Making HTTP Requests)
  • Axios with React.js (Fetching Data from APIs)
  • React Authentication with JWT (Secure Login Systems)
  • How to Deploy React App to Netlify
  • And many more things...

Meet Your Teacher

Teacher Profile Image

Code Bless You

Making Coding Easy To Learn

Teacher

Hi! I'm a passionate software engineer from Code Bless You and I love to teach about coding and general skills in less time. I've taught many people how to become professional software engineers.

My goal is to make coding fun for everyone. That's why my courses are simple, animated, and with practical implementation.

Learn by doing

Step-by-step tutorials and project-based learning.

Get support

One-on-one support from experts that truly want to help you.

don’t stress. have fun.

I can't wait to see you in class!

- Code Bless You

See full profile

Related Skills

Development Web Development
Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. React Masterclass Introduction: Welcome to the ultimate react course. In this course, we are going to learn react from its basis to more advanced concepts. So we will start with how react works. Why react is so popular understanding of Bb and JSX, building components, adding events, state variables, important hooks, accessing local storage, react street mode, filtering and shorting data, searching with autorizgons, routing and navigation using most popular library react Router Dom. After that, we will also see calling APIs, handling errors, showing loader functionality, managing and validate the form, pagination, infinite scrolling, user authentication and authorization with JSON web token, which is very important, calling protected APIs, creating the contexts, and much much more. If you are absolute beginner to react, you might don't know about these concepts. So let me show you the implementation of these concepts. By using these concepts, we will build three real world react applications. First one is task manager application, and we can say it's difficulty to basic. In this application, user can manage their daily task. So by using this form, we can add task with selecting the tags, and according to the status, it will display here. And also, we can remove this task from our application, so it can be best project for beginners. Now let me show you our second project, which is movie application. The amazing thing about this project is this data is real, which we are getting from another website. Also from here, we can filter our movie list and we can short it by date and rating and also ascending and descending. We can say it's difficulty level to intermediate. Now let me show you our third project. This project is very exciting. So we will build an ecommerce application which looks like this. You can see how beautiful this looks. In this project, we will implement many advanced concepts like routing, calling an API, infinite scrolling, shorting products by price or rating, searching products with auto suggestions, authentication, like sign up, login and logout, managing our shopping cart and much much more. And after completing this project, I will show you the deployment process of react application. Now you might ask who am I? I am a software engineer and also teach programming in easy to explain language using my YouTube channel. God bless you and with my online courses. Also, I will give you many tips and tricks which will help you a lot for creating better react applications. After completing this course, you will write react code with more confidence and using best techniques. I know you are excited to learn and build fast react applications. So let's jump in and dive into this course. 2. What is React?: Welcome to the first section of the ultimate react course. Now before we start learning react, let's properly understand what is react. React is an open source JavaScript library used for building front end applications. In simple words, with react, we can create fast and better front end applications. React was created by Facebook in 2011, currently, it is the most popular and most used JavaScript front end library. Also, there are other JavaScript libraries like Angular and view, but they are not as better as React. If you are looking for job as front end developer or full Stack developer, you should know how to create better and fast application with react. You might ask, what is special about react? Why react is so popular? Before react was created, when our web page loaded in a browser, our browser create tree like structure with our STML code. This tree structure called a Document Object Model or in short dom. Now, by using this doom in JavaScript, we can add various functionality for our application. Hiding the sidebar on button click, handling form inputs, et cetera. So here is the example of hiding sidebar on button click event. This is the code of Vanilla JavaScript, which means pure JavaScript code without using any external tools. Now imagine if we create large scale applications like Instagram or Amazon with Vanilla JavaScript. And how many lines of code we need to write? Even if we manage to write that long code, our code will become messy and hard to manage. Now, at that time, react comes in the picture. With react, we don't need to worry about writing Vanilla Javascript code. Instead of that, we will divide our application in small piece of code. This small piece of code is called a components and then react will take care about writing simple code for creating and updating dom. Components is used to write reusable and better organized code. Let me explain you with the example. So here we have our Project three, which is e commerce application. Here we can see we have New Bar, and at the right side of the Neb bar, we have a couple of links for different pages. So we can separately create Nabar component, and in that component, we can also add component for these links, and then we can reuse it multiple times for Ny Bar links. Now in the products page, we have sidebar and here we have the list of products, so we create another two components, sidebar and products list. Now in this product list, we have a couple of product cards, so we can define another component for product card and then reuse it multiple times in this product list. So we build all these components individually and then combine them to build our page. By creating small components, we can easily manage our code and our application also work fast. Also, with react, we can create single page application, which means our application loads only one time, and then all pages comes without reloading the entire page, and that will make our application almost 50% faster than normal SDML CSS and JavaScript applications. Now another reason why react is so fast is react has virtual dom feature. Now, this is the topic by which many developers get confused, but it is really simple. So let me explain you with one example. Imagine you have a jigsaw puzzle on your table. It's a beautiful landscape picture, and it contains many puzzle pieces that fit together to form the complete picture. Each puzzle piece represents a different part of your web page, like a header, a sidebar, or a main content section. Now let's say you have a magical assistant called Virtual puzzle solver. This assistant has an exact copy of your jigopuzzle, but it's virtual, not real. Now, whenever you want to make a change to your puzzle, you describe the changes to your virtual puzzle solver. Instead of directly manipulating the real puzzle pieces. For example, you might say, Hey, virtual puzzle solver, I want to move the blue piece from the bottom right corner to the top left corner. Instead of physically moving the puzzle piece on the real table, your assistant quickly looks at its own copy. Then figure out the changes needed and tells you right, remove the blue piece from the bottom right and add it to the top left. Now you make those changes on the real puzzle based on your assistant instructions. The benefit is your virtual puzzle solver can quickly identify which pieces you need to move to complete the updated picture without you manually rearranging every piece. In this example, the real jigsoPuzzle represents the real doom and the virtual puzzle solver represents the virtual dome in react. Now let's apply this concept to Rax Virtual doom. So when you build a web page with react, it maintains a virtual representation of your web page, and it is called as Virtual Dom. Whenever you want to update your web page, you describe the changes to the virtual dom instead of directly modifying the real doom. Reax Virtual doom efficiently compares the new virtual dom with the previous one. Same as your virtual puzzle solver, quickly identifying which puzzle PCs need to move on its own puzzle. After that, react knows exactly which part of real Dom need to change to mese the new virtual dom. By using this virtual dom approach, react optimize the process of updating the real doom, which means it only applies the necessary changes, making your webpage more efficient and responsive, especially when there are frequent updates or interactions happening. In summary, the virtual puzzle solver makes updating the real jigsa puzzle more manageable, DX Virtual doom makes updating the real doom smoother and more efficient, and also it enhance the performance and user experience for your web application. So that's it for the theory. For now, don't worry about all of these. You will understand these concepts when we create multiple projects. 3. Setup Development Environment: Let's set up a development environment for this course. So first of all, we need node JS. One thing I want to specify, we are just using one part of node JS, which is NPM called as Node Package Manager. This NPM is used to install react applications and some additional features. Head over to nodjs.org and download the latest stable version of NodeJS from here. Click on eight, and the download will start. And I have one suggestion if you already have NodeJS installed in your system, then please remove that version and install the latest version of node. Now open this setup and click on next. Accept the terms next, again, next, next, next, and install. And see installation process is started. And it's done. So we successfully install nodejs in our system. Now, let's verify this. So open command prompt in Windows, or if you are Mguser then open terminal and write node V, and hit Enter. If you successfully install nodejs, then you will see this version. If you get something node is not recognized as an internal or external command, then you have to install node again. After that, write NPM, and hit Enter. And we also get this version, lovely. Now the next thing we need for this course is Vascde, which is one of the best code editor and almost 95% developers use VSCode. So head over to code.visualstudio.com and install it. It is extremely easy. Open VS code and for making our coding experience good, we will install some extensions. Go to this external panel and first we search seven React Snippets and install this extension. This is one of the best extension for writing react JS code fast. After that, we have another cool extension called prettier. This is the extension every developer use in Vas code. Prettier will format your code in very organized manner. Install this extension. Nice. Now we have to do little settings for installation of prettier. In the installation section, scroll down the default formatter section and copy this first line of code. Now open up settings and at the top right corner, open setting, dogs and file and pase this line at the end. Save this file. Now back to setting and search format on save. Unable this and done. Now, one more thing, many students ask for my VS code theme. Search AU and install this theme extension. Now click on these settings and go to code theme and set it to AU border, and that's it. Our environment is ready. Now in the next lesson, we will create our first react application. 4. Creating React Application: So there are two ways to create react applications. First, we can use Create React app, or we can use white. Create React app is the old and takes more time to create. We will use white for creating the new react applications. So first of all, create one folder in which you want to practice react and open that folder in the command prom. And if you are Mc user, then open folder interminal now write NPM, create, white, at direct latest, and hit Enter to proceed, write Y, and hit Enter. Now write here your application name. I write first application, and hit Enter. Now here, we need to select the framework. So we select react and hit Enter. Now here, we can select Ja Script or TypeScript. Don't worry about that. Just simply select Ja script and hit Enter. In just second, our application is ready. This creates a basic react template, so we don't need to create react application from scratch. This command will give us a quick react template. Now here, we need to write these three commands. So first, we have to go inside our application by write CD, press tab, and hit Enter. Now write NPM, install and hit Enter. This command will install all packages that are needed to create a react application like webpack, which is used to bundle different files in one file. Another important package is Bible. This package is used to convert JSX, which is the modern JavaScript code which says JML code. So Bible converts that JSX into simple JavaScript code, which browsers can understand. Don't worry I will show you that in this section. Now simply write code, dot, and hit Enter. This command will open Curen folder in VS code. We can close this terminal. We don't need this. Now to run this react application in our system, we open terminal by pressing Control plus Peptic or Command plus BTI, and write NPM run dive and hit Enter. This command will take some time and here we get our application link of local host. Hold Control or command and click on this link. It will open our application in our browser. So this is what react Starter Pack looked like and see it is running at Local host 5173. So we successfully create our react application. Now in the next lesson, we will write first code in our react application. 5. Let's understand the React template: First of all, let's understand what we get in this react template. First, we get non modules folder. In this folder, we have all packages installed for our application. Without these node modules, we can run our react application, but don't worry we don't even touch this folder. The funny part is, when I create two to three projects in react, I don't even know what is this node modules folder does. I SOT, node modules is the folder where our all install packages and libraries stay. Next, we have the public folder. This public folder contains static assets that is served directly to the client. For example, here we have white tot SVG, which is our fab icon. Let me show you. Here in our browser tab, we can see our fab icon. After that, we have SRC folder, which means source folder. This is the folder in which we spend our almost all time for writing code. Here, we first have ASES folder. In this folder, we will put all our images, icons, ponds, et cetera, which we are going to use in our components. Next, we have a bunch of files. First one is app dot JSX, which is the root component of our application, which means this is the starting point of our component chain. Note that this Jx is the extension of react component. It is almost similar to dogs. We will see the difference in upcoming lessons. For now, let's open this and see how components looks like. All react components have this basic structure. At the top, we import some files like other components, CSS files, or we import objects from packages or logo, images, and all. After that, we have one function which has the same name as our component name. In this case, this is app. Now, this function always returns something which looks similar. HTML markup. But note that this is not the original DML markup. This is called JSX, which stands for JavaScript XML. So using this JSX, we can write STML and JavaScript code together, and this is the heart of react. So this is the part which decides how our website look like, and this code output is this, what we are seeing in our browser. And also JSX syntax is similar to STML markup. So we can easily write code in JavaScript in less code. And at the end in every component, we export that component as default, so we can use that in another file or component. Now, as you told before, Weblelibrary, take this JSX code and convert it into simple JavaScript code that our browser can understand. After that, we have app dot CSS file, which is used to style the app dot JSX file Markup. And also that we input at the top of app component. Next, we have main dot JSX file, which is the most important file of react. This is the file which connects our components with our index dot HTML file, which we have here. Don't worry, it is the same as we have our STML file. This is the main HTML file which is running in our browser. Let me show you. I change here this title to my first react app. Save this file, and in browser, see, here we get our updated title. And also, we don't need to refresh our page like SDML. React automatically reload our application when we save our file, and this is very cool. Now with that, we have F icon, which we see previously. Now, scroll down to the body section and see, here we have only two tags. First one is DU with an ID root. This is the main tag in which all components will show up. Let me show you. In our browser, right click on the page and go to Inspect. Here you can see we have our Du with ID root and inside this we have our app component. Now after that, we have Script tag, and here we link our main JSX file. Let's quickly see how code looks like inside main dot JSX file. At the top, we have some imports. Now after that, we have lines of code by which we can connect our app component that Du which have ID root. So we have react Dom, which we imported from react Dom client, and that has one method, create root. And inside this, it targets the root by document dot Get element by ID. After that, this root variable has one method called render, and inside this, we pass the component which we want to show in that root Du. Don't worry about this. In the next lesson, we will write all this code from scratch. Now after source folder, we have Getting nor file in which we can define which files or folder will not upload on Github. Next, we have package dot GSN file, which has all information about our application. You can see here name, version, and in this dependencies array, we have bunch of packages which are installed with installation, and also we have their version. If in future, we lost our nor models folder, then by using this package dot GSN file, can recreate our node modules. Now also we have scripts, which are sort cards for these commands. For example, previously, we used NPM run Dao for running our application. So internally, that runs this react script Dav command. After that, we have packages log dot JsN, which is essentially used to lock the dependency to a specific Vos and number. And at last, we have white dot confit js file, which is the configuration object of our application. For now, we don't need to worry about these other files. Primarily, our focus is on how to build fast and best react applications. 6. Writing Code from Scratch: Now let's write code from scratch. The reason why I want you to write code from scratch is because I want to show you how react components connect to the root element. First of all, delete the full source folder, we will build that from scratch. Now create a new folder called SRC and inside this, we create a new file called main dot Jx. Do you remember what this main Jx file does? Write? It will declare the root component, or we can see what we want to show in this DU with ID root. Now at the top, we import some objects from library and using that objects, we can connect our application with index DML file. First, import react object from react Library. If you are not familiar with this import or any JavaScript concepts, then don't worry write this code as I write because in the next section, we understand all useful concepts of JavaScript which we are using in react. Next, we import react Dom, from react Dom client. Now in the next line, we create one variable, const. Again, this is ES six da script feature, and I will show you that in the next section. So const and give your variable name. Let's say my first element. You can take whatever you want to. It's totally up to you. Equals to, here we write H one tag. This is my first element. And close the H one tag. Note that this is not a SDML markup. This is JSX, which looks like SDML because we didn't add any JavaScript. Now after that, we'll display this element in our root D. So we react, Dom, dot, create root. And inside this method, have to target our DU with root ID. So document dot get element by ID, and pass here root in double codes. And at last, we have to declare which element or component we want to display. So we write dot, render, and inside this, we pass our element, my first element. Save the changes and take a look. See, here we get our text. This is my first element. Now, let's verify this is inside our rootT or not. So right leg on the text and go to inspect. And you can see it is in our root due, so it's working. Congratulations, you created your first react app. Now here we add this element. But in the real react application, we will add here our app component. Don't worry about that. I promise you will comfortable with react soon and don't try to understand every topic in one go. Because with practice, you will understand each topic. 7. Section 02 JavaScript ES7 Refresher: Welcome to the second section of the ultimate react course. In this section, we are going to see some of the Javascript important topics which we use a lot in react. We start with War, was his let W his Cs ARwfuncton syntax, accessing object properties in different methods. After that, we will see object destructuring. So methods like map and filter, spread operator, ternary operator, modules, and much more. Some of these concepts you might already know, but see this section as a refresher. You are confident in your Javascript knowledge, then you can skip this section. It's totally up to you. The goal of this section is to make you ready with all the necessary concepts of JavaScript, which are used in react. So you can easily learn react without worrying about modern JavaScript concepts and put your hundred percent focus on learning react. 8. var, let and const: A t and const, these three keywords are used to define variables in JavaScript. Latin Const is new features in modern JavaScript. Most of the developers use Let and const instead of using War. Let's understand the difference between et const and War needed. In our previous project, which we create in first section, openmin dot JSX file, and here we remove all code. First question is what is wrong with war that we need to use new features for declaration. So I define here one function called print loop, and inside this function, we use simple for loop. First, we define variable, I equals to zero. Then we put condition I less than three, and at last, I plus plus. And inside this loop, we want to print this I value. So console dot log I. Now, at the end, we call this print loop function. Say the changes and take a look. See, here we get zero, one and two. Perfect. Now, let me show you what is the problem with war. So here, after this fall loop, we Console slide I. Can you guess what will our output look like? Let me show you. Save the changes and C, here we get this I value, which is three. So here we want to define variable I for only this for loop. In other programming languages, variable should only accessible for the block in which it defined, and that is called a scope. R is not a block scope variable. It is the functional scope variable, which means we can access this I variable inside this whole function. Now imagine we have to always come up with a new variable name. So to solve this issue in ESC Oxcope variable using two keywords, let and const. So we simply pass here let at the place of war, save the changes and take a look. See, here we get error, I is not defined. So now, this I variable is only accessible inside this four loop. We can say this block scope. We use war when we want to access variable in full function, but that is rare. Most of the time, we use late or const when we want to access that variable only inside the block of code in which they defined. Now you might think, what is the difference between late and const? Here, this const means constant. Constant means we cannot change it. Let me show you. Let's remove this code, and here we define two variables. First one with lat, X is equal to ten, and second one with const, Y is equal to ten. Now we can reassign the variable value which we declare with late. Here, we can do X is equal to 20, but we cannot reassign the variable value which we declare with const, so we can't write Y is equal to 20. It will give us error. And take. See, here we get type error assignment to constant variable. So if we want to want to change its value, then we use const and if you want to change its value, then we will use late. So to recap, don't use War keyword because it has functional scope and prefer to use Cs keyword before late. Only use at keyword when you want to reassign the 9. Arrow Function: So what is arrow function? Error function is another way to define JavaScript function. In other words, we can write JavaScript function in simple and easy way. This is very useful feature of Javascript when we are working in advanced topics. I add our previous code in source folder if you want to revise the concepts. Here we define function called say hello. Inside this function, we simply console dot log, and we want to print this Hello JavaScript world. We define this function with function keyword. Now let's see how to create the same function using arrow function. So for defining arrow function, first of all, we have to use let or const. But in most case, we use const because we don't want to reassign that function. Here we write our function name. Let's say, create equals to now we use parentheses for function, and then we use equal and greater than, which build this arrow. And then we add Ci brackets for adding Cd block for this arrow function. Inside this, we write console dot log. Hello JavaScript world. Now, let's call this function. Here, we can call arrow function by its name, same as we call our normal function. The changes and take a look. Open up Console and see here we get the same result. So both functions are same. This arrow function syntax will help us for advanced Javascript. Let me show you my trick for remember the syntax of this arrow function when I started learning Javascript. So we have our function say hello. Now, remove this function keyword and plays const. Then in between function name and parenthesis, we add equals to, and between the parenthesis and C brackets we add arrow, simple as. Now, if in arrow function code block, we have only one line, then we can remove these curly brackets. Let's remove these Save the changes and see how simple and easy to define function. Now, can you guys? How can we add arguments in arrow function? Right, it's the same way we pass in normal function. So we add here, language, and inside this console, we display this language parameter. Now when we call this function, we pass here, let's say react. Save the changes, and see, we get hello Javascript world react. 10. Accessing the objects: Let's talk a little bit about objects. So we know that object is a key value pair. In other words, JavaScript object is a collection of named value. You may know all about this, but I just want to make sure for you that the fundamental of Javascript concepts are right. So sorry for that if you know this. Just watch this lesson as a refresher. So here, I use const because I don't want to reassign this object with another value. So const user equals to in C brackets, we define data in key value pair. So first one is name to Halley. By the way, this is my favorite name. And another property, let's say, email and set to Halley 07 at the red gmail.com. Can you tell me how we can access this property? Right, we can use user dot name or user dot email. So we simply console dot log user dot name. Save this and see here we get Harley very easy. Now, let me show you another option for accessing the object value. So at the place of this dot name, we use square brackets and in double codes, we pass our property name. See, here we get Autoization also. Let's see, email, save the changes, and take a look. See here we get our email. We will use the square brackets method in some part of react. So that's why I add this lesson. 11. Object Destructuring: Now, another Javascript concept which used a lot in react is object destructuring. Let's see what it is. So imagine we have one object called user WtorsUser details like name to SAM and email to SAM email@gmail.com and country to US. In this code, we want to extract value of this object's property. Let's say name or email or country. For that, we write const name equals to user dot name. Next, we write const email equals to user dot email. And at last, we write cons country equals to user dot country. And after that, we simply print these values. So console dot log, name, email, country. Save the changes and take a look. See here we get these values. Now the problem with this code is the number of lines. Imagine we have five to ten properties then we have to declare five to ten different variables, and that is not the best practice. To solve this issue, we have object destructuring. I comment out this previous code and write here, const Now here we have to use ulipacket equals to our object name which is user. Now you think what we have to write in this Cali brackets. We have to write here only our variable names which we want to extract from this object. We write name, email, country, and that's it. This single line code works the same as these three lines of code. Let's verify this. Save the changes and see it works the same as before. You can see how simple it is with object destructuring. Now you might ask, does we have to always add all properties in the Calibacket and the answer is no. We have to only add those properties name, which we want to extract. For example, if we want to access only name and email, then we can remove this country variable. Now, what if we want to change this name variable name to let's say user name? So for that, we have to add here colon and after that, we add user name. Let's verify this works or not. Change your name to user name, save the changes, and take a look. See, it's working. This we called as object destructuring. 12. Map method: Now in this lesson, we will see map method for array. This is one of the most used array method in react application. In react, we will use map method to display the list of data. For example, imagine we are working on E Commerce project. Now, in that project, we have array of products which we want to display. Here we use map method to display each product. Don't worry, just say this and you will understand this. We create here new products array equals to here we add product one, comma product two, and comma product three. Now we want to display each product list item like this. So we can do that by using MP method. So we write here products dot MAP. Now in this map method, we have to pass a callback function which runs for each item. So let's define function here. Now, how can we get value of each element in this function? We get each element value by using the first parameter in this function. Let's say item or product. You can use descriptive name. Now, we simply return in double codes, list item tag. Now what we want to add here? Yes, this product. So add plus product, plus, and we add in double codes, closing list item. Remember that this map method returns a new array. It will not change the previous array. So let's store this new array in variable called display items. And after that, we simply console dot log display items. Save the changes and take a look. See, we get array of list items. So always remember whatever we return from this function, it will add in new array. And this function runs for each item, simple as that. Now this code looks a little bit long, so we can use arrow function syntax, remove function keyword and add here arrow. Now we can even simplify this code because in this function, we have only one line which is written. So we remove this written and we can also remove the Car brackets. See now our code looks easy to read. Let's verify these works or not. Save the changes and take a look. See, it works the same as before. Now here, this looks a little bit ugly. Instead of using these double codes, we can use template literals. This is very simple and useful. We remove this whole statement and add here backticks inside these, we write our opening list item and closing list item. At the center of the tags, we have to add this single product. So in template literals, if we want to add variable, then we have to use Dollar and Cali brackets. And inside these, we can access this variable product. Save the changes and take a look. See, again, we get the same result. So it's totally up to you which syntax you want to use. Now in the next lesson, we will see another array method, which is filter. 13. Filter Method: Let's see filter method, which is used to filter array. In simple words, filter is used to remove items from existing array and it will always returns a new array. In our previous ecommerce example, imagine we have to add search functionality for product names. By using this filter method, we can filter existing array according to our choice. Let me show you what I mean. I am removing the previous code, but for your reference, I will add it in a separate folder, so you can get it for revision. So here we create a new array called ages equals to in square packet, five, 23, 14, 30, and 21. Let's simply console dot log this array. Now, let's say we want to filter out edges which are 18 plus. We write ages dot filter. Now inside this, we pass function, same as we done in map method. We can define function, or we can also use arrow function syntax. How can we get each array item in this function? Right, bypassing the variable at first parameter. We add here variable called age. In this age, we get each item of this array. First, we get here five, then we get 23 and then 14 and 30 and 21. Now in this function, we have to return condition. Let's say, age greater than 18. Which element pass this condition, that element will add in new array. So first, that filter method, check condition for f, which will not pass this condition so that filter method doesn't do anything. Then it checks condition for 23, which will pass this condition, so it will add a new array. After that 14, which will not pass. After that 30, which will pass this condition, so it will add 30 and then also add 21. Now, this filter method always returns a new array. Let's store that in variable called adults, at the end, let's console dot log these adults. Save the changes and see here we get 23, 30 and 21. Here we can also remove this return and call the brackets. See it looks simpler. Just remember that which element pass this condition that we add innu array, simple as that. Now, let's say from this array, we want to remove this 30. Here we pass age does not equals to 30. Save this and see without 30, we get all elements. So that's how we use filter method for filter out data. 14. Spread Operator: Now, another useful feature of modern JavaScript is the spread operator. So here we create one array called array one, and we add here one, two, three, and four. Now, after that, we define another array called array two. And we add here seven, eight, nine, and ten. How can we combine these two array in single array? So to combine this array, we create a new constant numbers equals to array one dot. Here we use concat method, which is used to combine two or multiple arrays. And inside this concat method, we pass our second array, which is array two. Let's see what we get. Console dot log this numbers array. Save the changes and take a look. See, we successfully combine these two arrays. Now, let me give you one little exercise. Here we want to add missing numbers between these two arrays. So our output should look like this one to ten in order. Pause this lesson and try to add five and six between these arrays. Now, I also try to solve this with another method. If you have your method, then you can pose that in Q&A section. So we create one new array with five and six. And in the concat method, we add that array before array two. And with that, we get our result. Now, let me show you the modern way to do that. So we comment out this line and write const numbers equals to now here we create array, and inside this, first, we need to get all values from array one. So we write dot, dot, dot, which is called a spread operator, and then we add our array name, which is array one. This expression will return all values of this array one. Now, after that, we want to add array two. So we write again spread operator array two. Save this and take a look. See, here we get this both array combined. Now you might ask, we want to add five and six between these. So for that, we don't need to create any new array like we did before. So where we want to add our elements, we can simply write it at that place. If we want to add something at the beginning or end, we can also simply do that, save the genes and take a look. See, here we get five and six. You can see by using spread operator, we don't need to worry about anything. Just write dot, dot, dot, an array name, and we get all values of that array. Simple as that. We can also use the spread operator with objects. So here we define constant object one. And inside this, we add name to meth. And after that, we define another constant object two. And inside this, we add hobby to array teaching and learning. Now we want to combine these both objects. So we define constant, let's say user equals two. Now here we have to use objects because we want to get new object, and what we write here, write, spread operator, object one, com spread operator, object two. And after this, let's simply consult dot log this user object. Save the changes and take a look. See, here we combine two objects. Now as we do in array, we can also add more properties in this object. We add here, let's say, YouTube to code plus. Save this and see, here we get our property. You can see how simple to combine arrays and objects using spread operator. That's why spread operator is very useful. 15. Ternary Operators: So in this lesson, we will learn about ternary operator or conditional operator. From its name, you can guess what it will be used for. Right, it is used for adding condition. In simple words, ternary operator are the shortcut way to write Is condition. So here is a syntax of ternary operator. At the first position, we have our condition. After that, we have question mark, which basically means if and then we have true expression, which will execute if condition is true. And then we have column, which stands for se, and if condition is false, then this false expression will execute. So I simple words, if condition is true, then first expression will run, se second expression will run. Let's see this practically. Let's remove this code, and we simply create one variable using const Mx equals to 50. Now, after that, we want to add condition. If max is greater than 35, then we want to return, pass, else we return, fail. So we write our condition at the first position, which is max greater than 35. We add question mark, and we adhere string, which we want to return. So in codes, pass, and after that, we add colon, and we add here string in codes, fail. Now here we are returning string from this expression, so we have to store that in variable. Let's say result. And at the end, simply console dot log this result. Save the changes and take a look. See, here we get pass because our max is greater than 35. Now, if we change our max to 30, save this and see here we get fail. So you can see how simple it is to use ternary operators if we have single line expression. If we have to write the same code in ELs condition, then we have to write it in this way. So first, we declare result variable. Then we add ELs condition for filling this result. See here we use let because we want to reassign that variable value. Anyways, you can see how ternary operator reduce the lines of code for adding EFLs condition. That's the beauty of modern JavaScript features. This arrow function Dinari operators are little things that will boost your speed for writing code and reduce the lines of code. Smart developer is not who writes more number of lines. Smart developer is who can write code in less number of lines, but still it works better than wrong code. 16. Modules in JavaScript: Modules are one of the most important concepts of modern JavaScript used in react, or we can say react works on modules. So let's start with what is module. Module is a file that contains code to perform a specific task. It can contain variables, objects, function, and so on. So as our application grows, we have to write thousands line of code. But instead of putting everything in single file, we can divide our code into separate files by their functionality, which we can call as modules. And by using these modules, we can make our code organized and super easy to manage. Let's see this practically. So let's remove this previous code, and we simply create one function called post for our application. For now just imagine this function will return the UI part of single post. In this function, we write console dot log. This is post. Now, after that, we create one more function called feed for displaying multiple post inside this function, first we write console dot log. This is feed and after that, we call here this post function. As we imagine this post function returns the post UI, and this feeled function will return the multiple post. We simply call this post function multiple times. I know this is a little confusing, but don't worry about this. In the end of this lesson, this all makes sense. Let's see what we get here. So at the end, we call this feed function, save the changes, and take a look. See, first we get here, this is feed, and after that, we have multiple posts. Now, this is just one part of our application. We have more functions or we can say more parts, then managing this code will not easy. So we can divide this code into multiple parts called modules, and then we can easily manage our code, and we can also reuse that code in different applications. So we cut this post function from here and in our source folder, we create a new file called post dot jsx, and this is also called a post module. And inside this file, we just paste this post function. Now we might have question, how can we use this post function into our main dot JSX file? Because currently we can access this post function in only the postjsx file. First of all, we have to make this function public so we can access this function in other modules. For that, at the beginning, we simply add export keyboard. Now as we export, we can access this post function into any files. So in main or JSX file, we have to import that function. So at the top, we write import Cali brackets, and in these CL brackets, we have to add our function name which we want to import. In our case, it is post from now in codes, we have to write the path of the modules from which we want to import. So we write period or dot and slash. This refer to current folder and see, here we get the suggestions. Select post and done. Note that here we can also write post dot GSX file if we have post dot TXT or any other post file with other extensions, but that is rare. So we always don't write this dot GSX extension. Save the changes and take a look. See, it works the same as before. We successfully create our first module. Now, let me give you a little fun challenge. Here we create post module. You have to create feed module separate from this main dot Gx file and call that feed function in this main dot JSX file. I know you can do that. Just give it a little try. So pause this lesson and after that, see this solution. I hope you solve this exercise. If you can't complete this exercise, don't worry. Now you can learn that we are all here for learning. But important thing is, at least you try to solve that. So give yourself credit for that. So first of all, in main dot Jx five, we cut this feed function with the import statement because we are using post function only inside this feed function. And we create a new file called feed dot JSX, and inside this file, we paste this feed function. Now to make this function accessible in other files, we have to export this. Save this, and in main JSX file at the top, we import Cali brackets and what we pass inside this. Write function or variable name which we want to access. So we add feed from codes, period, slash, and we select feed. Save the changes and take a look. See it works the same as before. So you can see how we split or divide our code into multiple files called modules. And if you learn this module system, then you can easily understand react components. Now in the next lesson, we will see a little different way to export and import modules, which we used a lot in upcoming section. 17. Export as Default: Now in the previous lesson, we define modules and export them to make them accessible for other modules. Now imagine we have one more function in this feed module called another function. And inside this, we simply console dot log Another function. Now to export this function, we add here the export keyword, save this and in main dot Jx file, we can also import that another function. Here, we remove this feed from Import and just press Control plus space in Windows or Command plus space in Mac for open suggestion list. Now here we can see the list of exported objects or function. D is we call as name export, which means by using the name of variable, we can import them. But there is another way of exporting, which is export as default. So I feed dot JSX file, I want to make this feed function, which is the main function of this feed module, export that as default. So to make export as default, we just add export default at the place of export. Simple as that. You might think, what is the difference between this export and export default. The only difference is in the import statement. Let me show you what I mean. Save this file and in main Jx file at the place of the curly brackets, we adhere directly feed, and that's it. Here we can give any name to that function. This is the only difference. Now, if we want to also import another function from feed module, then we can also import using comma curly brackets and here we can import all our named export from feed module. Now you might ask why we need to learn this export default? Because in react, we will also see this default export for exporting all components. I don't want you will confuse by looking another syntax of export. Now in this feed dot GXS file, this export default looks a little bit ugly. We can remove this at the bottom, we add export default, and here we pass our object or variable name, which we want to export, which is feed. And we can also remove this export and after default export, we write export and in object, we pass our function or variable name, simple as that. To sum up for default export, our import statement look like this. And for named export, our import statement look like this. Just we have to use Cal brackets. That's all about modules and exports. Congratulations. Now you are completely ready to learn react Jazz. If you are continuously watching this course, take five to ten minute break from your screen and get some fresh air, and I see you in the next section. 18. Section 03 React Basic Concepts: Welcome to the react basic section. In this section, you will learn some of the basic concepts which are very important in react. We start with building components, understanding JAX and web, adding elements, adding Javascript expression, attributes, events. After that, most important concept of react, which is state and also one of the most used hook used state. Handling inputs, mapping list, and much more. I'm very excited about this section and hope you are too, because using these concepts, we are going to build our first application in the next section. So let's do this. 19. Setting up new project: Let's first of all, create a brand new application, which we are going to use in our first project. So open up command prompt or terminal in your folder in which you want to create this application. And do you remember how to create react application? Write using NPM, create white at the red latest? Now write our application name, which is task track and hit Enter. Make sure we always write our application name in small case and without any underscore. Otherwise, it will give us error. Now here we select react application, and after that, we select JavaScript variant. Good. Now, let's run these three commands. So first of all, we have to change directory by CD and press Tab two times. Now let's install all packages and library by using NPM Install. And it's done. Now, let's open this new project in VS code. So we write code space period. This will open VS code in this directory. Let's close this command prompt. We don't need this. Great. Now let's verify we successfully set up our application or not. Open up terminal by using Control plus Batak or Command plus Bata and simply write NPM run DV and hit Enter. See, we get this react template, and that means we successfully set up our application. 20. Building own component: Now in this lesson, we will build our first react component. To quick recap, the component is reusable piece of code that used to define certain part of user interface. Here in the source folder, we create a new folder called components. In this folder, we store all components of our application except our root component, which is this app component. Now in this folder, we create a new file called card dot JSX or Js now you might have question, what is the difference between JSX and JS extension? First of all, we can write any extension because they both work same. But generally, we use JSX extension because when our application grow, we may have to write some JavaScript code. At that time, this JSX extension will tell you which file is rear component and which file is just Vanilla JavaScript code. Also, when we use dot JSX, our code editor can give us better service like syntax suggestion, error checking, and other features. Used to write JSX code. But some developers also use dot js extension, and if you are working on single project with multiple developers, then you have to use the same extension that they are already using. So here we use dot JSX. These are the little details which many experienced developers doesn't know and interviewer like to ask this kind of question. So you can note this point. And one more thing, always write component name with capital letter. Otherwise, it will not work in browser. I will tell you reason in the upcoming lesson. Now in this component at the top, we have to import react from react package. After that, we have to define here function or class, which will return JSX. So these are two types of react components, functional components and class components. Class components are little old for current time because for implementing class components, we have to learn some of the advanced concepts of JavaScript. And also, class component is little complex than functional component. When Facebook developed, react first time, are only one component type which is class component. But as react develop, it had functional components and that makes react very simple and easy. Currently, almost all developers switch to functional component and that's why I decide to create discourse using functional components. Here we define function with the same name of our component, which is card. And inside this function, we will simply return H one tag with text, let's say, card component. Note that we can also create function by using R function syntax, and that's it. We create our first react component. You can see how simple it is to create react component. Just we have to import react from react library, and after that, one function with component name and return the element which we want to display. Now, let's verify these works or not. As we know, we have to add this component in main or JSX file render method. So for that, we have to export this card function from this card component. We remember how we export function from the module right by using Export keyword. You are doing really great. So write export, and this card function is our main method. So we can export default and write here function name card. Save this, and now we have to import this card function in main dot sx file. So here, after this app input, we import card from, and in codes, we have to pass our file path. So period components card. Now at the place of this app component, we simply pass card component. Save this file and take a look. See, here we get our H one tag with text. So this is really, really simple to create components in react. If you're a little confused, don't worry with practice, you will master react. When I first started learning react, I was also confused, but I kept learning and most important practicing. Now here, I have one shortcut trick for creating the basic structure of components in just 1 second. Make sure you install the ES seven react Nippet extension. This is necessary for that. So we remove this complete code and just write here RAFCE which stands for react arrow function component with export and press tab. See, here we get the boilerplate for react components. By using these, we don't need to manually type this import function, and export statements again and again. Praise cap for single cursor and right here card component. Use the changes and take a look. See, it works the same. Now you might ask, why don't I show you this sort cut at the beginning? So the reason is I want to explain you the complete structure of creating components. If I first show you this trick, then you cannot understand components properly. And I bet you understand creating component very well. Now, let me give you a little exercise. Have to create another rea component called create todo. In return simple tags, create new todo from here in H one tag. I'm sure you can complete this exercise. 21. Solution of this exercise: Now, before we start our next lesson, let me show you solution of previous exercise really quick. So in this components folder, we create a new file called createdo dot jsx. And inside this component, we write RAA, CE and press step, and our component is ready. Now press Escape and at the place of this D, we write h one tag and create new todo from here. Save these and in main dot jsx pile, we import create to do, and we can also see suggestions here. Select the suggestion, and this will import our component from our folder. Now, we simply pass here, create to do. Save the changes and see, here we get our create to do component. If you can't complete this exercise, then also don't worry. You can again watch the previous lesson. It is okay. There is no pressure at all. 22. How JSX and Babel works: Now in the previous lesson, we create our component and we also written code looks the same as HTML code. But as I told you before, this is not HTML code. It is JSX, which is modern code for writing STML and JavaScript together. We've seen this in section, but that is just a little introduction. Now, let's understand how it works internally. So as you may know, our browser can't understand JSX code, but it can understand Vanilla JavaScript code. We have to convert our JSX code in Vanilla JavaScript code, so our browser can understand it. For that, we need a compiler called Babble. It will convert our JSX code into plain JavaScript code, which browsers can understand and render. Let me show you that practically. In our browser, open a new tab and head over to Bblejs dot IO. And go to this write out section. So here we can write our modern JavaScript code, and Babble will convert that code into JavaScript code which browsers can understand. So here we simply write const heading equals to H one tag. And pass here string. This is JSX. And see, here we get this code. So JSX convert into this JSX function. Now first argument of this method is H one, which is our element type. And the second argument is the object which have property called children. Basically, children is what we pass inside our element. Now here, we can also pass class attribute equals to main heading and see here we get class property in this object. For developers, writing code using JSX is more simple and easy instead of writing this vanilla JavaScript code. So in short, we always use JSX for our components, and Webble will compile our code into this JSX function. And that's the reason we don't have to compulsory import react library at the top. But before React 18 update, we need to import react at the top. Now you might think, how can we see the old method of react dot create element? So here, in this option, we have react run time. By default, it is set to automatic, which is this JSX function, and we can change that to classic. And see here we get this old method of transforming JSS code into JaaScript code using read dot create element method. If you want to read more on this topic, then you can read this article. I will attach official documentation link. So that's how JSX and Babel works in react application. 23. Adding Elements in Components: Now in this lesson, we will add some elements in our component. So after this heading tag, we want to add one button. So we add button called at task. Now here we get error in our JSX expression. Let's over this and see we get JSX expression must have one parent element. Now you might think why. So in the previous lesson, I show you JSX expression is converted in JSX runtime function. And also, we have seen reatt create element method. In this both method, here we can only specify one element. So if we write multiple elements in JSX, we will get confused which element should pick. So in JSX, we always add elements in one parent element. So we add here Du and move our code between this die. Save the changes and see prettier format our code in structured manner. So that's why developers love prettier so much and prettier also add this parenthesis and semicolon here. That's because of JavaScript auto semicolon insertion. For example, if we have only return and nothing else in that line, then JavaScript automatically put semicolon here. Let me show you. We move our JSX into next line. Now if we save this file, see Ja script ad here Sami Colin because of that, these next lines will never get executed. That's why prettier ad here parenthesis, save the changes and take a look. See here we get heading and button. Let's inspect eight so we can also see the markup. Here in the root du, we get our du and inside this du we have our elements. Now sometimes we don't want to add this unwanted div for every react components. Let's see another method for adding multiple elements. In react, we have one method called fragment. This fragment is used to add parent element in our JSX, but it will not return any UI component on browser. Let me show you what I mean. So at the place of this Du we write react dot fragment. Now if you wonder how I change this opening and closing texts together, it's because I'm using this autoem tag extension. You can also install this extension or increase your typing speed. And here are the current install extension which I used, so you can also check them. This material icon theme is for Con's theme. I like that a lot. Now back to our topic, add react fragment as parent element. Save the changes and take a look. See, in the inspect, we have here only our two elements without that unwanted due. Now also, there is one more shortcut and easy method to add react fragments. We can simply remove this react dot fragment, and that's it. These empty tags are also works the same as react fragments. Save the changes and see it works the same. 24. JavaScript expression in JSX: So in the previous lesson, we had multiple SDML elements in our JSX. Now, let's see how to add a Javascript expression or code into JSX. So instead of showing this text, we want to show total number of tasks like this. Now, this zero is hard coded, but we want to show the actual number of task dynamically. So just for demo before our written statement, we create one variable called task equals to, let's say, five. Now, how can we show this task variable at the place of this hard coded number? And the answer is very simple. So remove this number and adhere Cully brackets. And between these cul brackets, we can add any valid JavaScript expression. So we add here task variable, save the changes, and see here we get five. Let's change this task to zero, and also we can add text at the beginning or after this ci brackets. Save this and see, here we get task zero. So between these cul brackets, we can write any Javascript expression. This expression should return a value which will display at deposition. For example, if we write here only true and save this we get nothing. So if we do not want to display anything, then why we write here that expression in JSX. So that's why I'm telling you to add expression, which returns a value, or we can even call function, which can return a value. So after this task, we create one function, called count task, error function, and inside this, we return this task variable. And at the place of this task, we call count task function. Save the changes and take a look. See, here we get zero again. Now let's make this core little interesting as an exercise. So in this function, when this task variable is set to zero, we want to show a message, no task available, else, it is current task number. This is really pretty simple. I hope you can do that. Hints, we can remove this task text and return complete string from this function. So spend some time on this exercise, and after that, you can watch the solution. So first of all, in this function, we add condition if task equals to zero, then we return no task available. And else we return string using template string. If you don't know that in template string, we can access variable with string. Just see this, we add acti, task, colon, and to access variable, we add dollar curly brackets and task. Now, let's remove this task from Jx. We don't need that. Say in and take a look. See, here we get no task available. And if we change our task to two, and see we get here task, too. You can see how simple it is. I know you completed this exercise, or at least you tried to solve that. So take credit for that. Now, let me show you shortcut rig for writing this same code. So I comment out this code and at the place of using Ils, we use ternary operators, which we have seen in previous section. So write return, and first, we add condition, task equals to zero. Now add question mark for true and return here, no task available. After that, colon for falls, and return here ticks, task, colon, dollar, ci brackets, task. Save this and see it works the same as before. We can test it by changing its value to zero. And see we get no task available. 25. Setting attributes in elements: Now, let's see how we can add attributes in these elements. It is really simple. We can do that same as we do in SDML. For example, we want to add here value property for this button. So we simply add here value equals to at task button. Now let's make this button disable dynamically. So in our function, we define a new variable called Hide button, equals to true. Now, when this height button variable is set to true, we disable our at task button. So here we write disable equals to now to excess variable, we add curly brackets and pass here Hide button. Save this and see our button is disabled. And if we set our variable to falls, then our button is unable. That's how we use simple and dynamic attributes inside elements. Now, let me ask you one question. How can we pass class attribute for elements? You might say class equals two, and we pass class name here, but that will give us warning. Let's save these and open Console. See, here we get this warning invalid dom property class, and it also give us suggestion, Did you mean class name? I JSX, we have to use class name attribute instead of using simple class. But why? So as I told you before, this JSX expression convert in simple Javascript object, and in that object, if we use class attribute and in JavaScript, class keyword already reserved. So that's why in react, we use class name at the place of class attribute. Now another important and different attribute is styles, which used to specify an inline style for an element. So in plains TML, we write something like this. Style equals to, and in double codes, we write our styles, let's say, color to red. Save this and C, we get here error, which says we have to use here values, not a string. In JSX, we have to set this style attribute to plain Ja script object, which contains styles. At the top, we create one object called styles equals to object. Now we have to pass all CSS properties in camel case notation, which means except first letter, every first letter of new word is capital. For example, if you want to add background color, then we write background and new word which is color which C and pass value to red. I know this is a little confusing, but don't worry 99% time, we don't even use these inline styles. Now, let's pass this styles object in this style attribute. For that, we add here Cali brackets because we are adding JavaScript and add here Styles object. Save the changes and take a look. See, here we get this red background. Now, some developers don't define this object separately. They add it directly in the curly brackets. Let me show you. So we cut this object from here and paste it at this styles object. So these first two Calibackets are for accessing JavaScript and for style, we have to pass object, which is another Calibacket that's make these inline styles very confusing and hard to manage. And that's why we usually don't use inline styles in JSX. So let's remove these inline styles and also remove these styles variable. 26. Events in React: Now let's talk about how we can define or handle events in react. So handling events in react is very similar to handling events in STML. Let's first of all, clean our component, so we remove this constant, accept this task, and also remove this function and remove this H one element. And between these, we pass task calibracets task, and also remove this disable property. Perfect. Now, as I told Liu, all react elements as events based on SGML events. For example, here we want to add click event on this at Task button. So here we have on click we also have on double click. Add here on click event equals to and in C brackets. Now can you tell me why we are adding here ci brackets? It's because we have to add here JavaScript expression. In this case, we will add function which runs on this button click. Now in react, we have popular naming convention for handling events. We create all events methods name, start with handle. By just looking the function or method name, we can say this is for handling this event. So here we create function call handleClick. If we're handling double click, then this name will be handle Double click. A notice that most of the time we use CamelCase notation. So handle click arrow function, and inside this function, we simply console dot log at task. Now we have to pass this function reference in this on click event. So right here, handle click. Save the changes and take a look. Click on this button and see we are getting at task message. Now, make sure we don't call this function because if we call that function here, then it will only run when these components get render on the browser. Now in this function, we want to increment a number of tasks. So for that, first of all, we have to make this constant to t because we want to reassign its value. And in our function, here we simply write task plus plus. Save the changes and take a look. Click on at Task button, and you can see task counts are not updating on page, but we are getting this at task message. It means function is working fine. So let's check this task value is increasing or not. So after this message, we add comma and add task variable. Save this and repress this page. Click on the button and you can see values are increasing, but it will not reflect on the web page, and that's the topic of next lesson. No. 27. What is State: So in the previous lesson, we saw our task value is increasing, but it's not updating on dom. So when we want to display something change on our dom, then we can define that variable or object or array is the normal JavaScript variable. So for displaying the change on dom, we have state in react. This state allow us to manage and display the changing data in our application. So when we define our variable as normal Javascript variable, then react will not reflect that changes if we change that variable value. But if we define our variable as state, then react will reflect that changes if we change that variable value. So in simple words, state is used to tell react what this variable, and if it change, then reflect that change on the dom. So as we know, react has virtual dom. When we change the state of one component, react get this new component and compare this new component with the old component and then only reflect those changes on the real dom. Simple as that. State is very important concept of react, and many beginner developers struggle with this concept, but don't worry, your all doubts will clear when you see this practically. Now you might ask, how can we define a variable as a state? So to define variable as a state in functional component, how to use one hook. But before using hook, let's understand what is hook. 28. Introduction of React Hooks: So what are hooks? Hooks are the functions to use some react features in functional components. In other words, we can say that hooks are functions that make functional components work like class components. I know this sounds a little complicated, but it's not. Let's understand with this story. Before react launched hooks, there is only one way to use state and lifecycle methods by using the class components. Developers had some problems with class components, such as class are a bit difficult, especially for those who just started to react. Confusing with this keyword, and we have to write all boilerplate again and again when we create a new component. So react takes some time to develop special functions. We can use in functional component and that special functions are called as hooks. So I think now you understand what is react hooks, which are functions that make functional components work like class components. And nowadays, hooks are very important concept of react, which every react developer needs to learn. Now in the next lesson, we will see the first hook which is used to define variable as a state. 29. useState Hook: Now let's define this task as the state variable. For defining state, we have one hook called use state, and this is one of the most important and most used hook in react. So to use any hook, first, we need to import that hook from the react library. A all hooks name start with the prefix use. All those functions that start with use are react hooks. At the top, after this react, we add comma and in Ci brackets we import use state. Now in our functional component, we call this used hook. Inside this, we have to pass default value of the variable, which is zero because we want to set task as zero. Now, this function will return an array. Let's store that in variable called count array. After that, let's simply consult dot log this count array to just see what is inside this array. Save the changes and take a look. See, this array has two elements. The first element is our original value, which is zero, and the second element is one function. Let me show you. So first of all, we store first element, count array index zero in variable called count. And now let's display this Tate variable on webpage. So here, I'm not removing this normal variable because I want to show you the difference. So we duplicate this line by pressing sift plus alter, plus down arrow in Windows and Saft plus Opson plus down arrow in Mac. These are little trigs which will increase your overall speed. Now at the place of this task variable, here we add count. Save this and see this both looks the same. Now let's see how we can update this count state value. So for updating the state value, we have function as second element in this use state. So back to VS code, and we store this count at a second element, in variable called set count. This is the common naming convention for state. So value of the state, we called a normal variable name and function which can set the value of that variable, we had set prefix for that function name. For example, count, set count, loading, set loading, et cetera. Whatever value we pass in this set count function, it will be the value of this count variable. Let me show you what I mean. So here we want to increase this count by one when we click on this at Task button. So we write set count, and inside this, we want current value, which is count and plus one. So when we click on this button, first, it will get the current value of count and then add one in it, and this set count function will set this value, which is zero plus one as this count, simple as. Save the changes and take a look. Click on this button and see count state is increasing by one, but task variable are still same, and also tasks are always stay to one. Why? Because when any state change in our component, whole components gets rendered or we can say run again. And that's why task is always stay at one. Don't worry. We will understand that rendering in detail in upcoming section. Another thing, if we refresh the page, this count again start with zero because here we set default value as zero. If we pass here five, then on refresh, we get here five. So now let's remove this task variable and also remove this actuan tag. Now here our code looks a little bit ugly because we can see for creating one state variable, we have to write three lines of code. Imagine if we have three to four state variables, then how mess our code looks. Let's make this code shorter using array destructuring. Let me show you. I comment out these three lines and we write here use state, and inside these, we pass default value to zero. Let's store this in variable and at the place of variable name, we add square brackets and inside that, first, write the first variable name, which is count and then write function name, which is set count. This single line works the same as these three lines, and that will make our code clean and easy to maintain. Let's recap this use tt hook. Used tt is used to create state variables in functional component. To use the used hook, we need to first import that and use it inside the functional component. Here we can pass any type of data like Boolean, number, text, object, array, anything, and then store it using array destructuring. The first variable is its current value, and the second variable is the function for updating that value. Simple as that. I know some people gets a little confused here. I was also confused when I learned used it hook for the first time. But with practice, I learned this concept and use that in my projects. 30. Handling user inputs: Now, many times in our application, we have to take users input. For example, user fill Long in form or user writes something in search bar, then we need to get that input value in our component. So let's create one input with type text. Now, when we write something in this input box, we want to display that value. So for that, we adhere onchange event, which runs every time when something changed in that input box. Same as we do in Vanda Javascript. So in this change event, we had function called handle change. Now, let's define this function. So const, handle change equals to, here we use arrow function. Now in this, we want to Consult dot log current inputed value. For that, we have to pass here event object, and this event object contains various information about that input field. So write CLG pcsle dot log and add here event dot target dot value. This expression will return the current value of that input box. Save the changes and take a look, write something and see here we get these values, so it's working. Now we want to show this current text on our web page. So can you guess what we will let me give you a little hint. This current value is changing, and we need to display that changes. Can we use normal variables? No, then what we will use? Right, we use use state. Now, before using us state, let's remove these three lines of code. We don't want that. And also, we remove this task plus plus and console dot log from handleClick function. Now here is the one more thing. We always define our use state hook at the top in our function component, so we can use that state in whole function. So we call here use state, and inside this, we pass our default value. And for input, we want to set it to empty string. Now, let's store this in variable, and we use here array restructuring, input and set input. Now in this handle change function at the place of this console dot log, we write set input function, simple as set. Now at the end, let's display the current input. So add another h one tag and input to Ci Brackets input. Save the changes and take a look, write something here and see immediately we are getting the current value. So that's how we get value of inputs in react. Here, I have a little bonus for you, and that's the shortcut way to write this use state line. So just write use state. If you're not getting this, then install that ES seven extension, which I told you to install in the beginning of this course. Select that and see here we get template for use state. Here we get multiple cursor, which will change this both name. So write input and press tab. This will automatically write set input in camel case and pass here default value, empty string, and press escape, and our new state variable is ready. This is the beauty of des extension. So I hope you like this trick. Now in the next lesson, we will see how to display list and react. 31. Mapping Lists: Now let's see how we can display the list of arrays in react. For example, here we create one array called task, and for now, we just add here Task one, task two, and task three. Now here we have to display each task on our web page like this. We add one unordered list, and inside this, we add three list items. We have to do that using the map method. So here, we have to add calibrackets, because we are going to add here JavaScript expression. So task dot MAP and inside this, we get each task arrow function, and now we simply return here JSX, which is list item. Let me explain to you what is happening here. So when we use map method in this single task, first we get this task one. So we have to display this task string here between this JSX element. So again, we use cul brackets for accessing Javascript expression inside JSX, and we pass here this task. Simple as that. Now, let's add here our under list, and inside this, we will move our list items. Save the changes and take a look. See here we get this list with all items. If you have doubts about map method, then you can again watch MP method lesson in JavaScript refresher. Now, here is one little issue. In our console, we get this error. Each child in a list should have a unique key prop. The reason we are getting this errors because we need to uniquely identify each item of this list because if something changed in any of this list item in virtual dom react needs to quickly identify which item changed, and according to that, react need to update the real dom. So back to VS code, and always remember when we use MP method in react, we need to pass unique key for returning element. So we write here key, and here we have to pass a unique dynamic value, which is this task string. So we simply pass this task. Here we are using this task string, but in real world application, we have each task object with a unique ID, and at that time, we pass task dot ID. Don't worry about that. We will also see that in the upcoming sections. And also note that this key should only need to be unique in this current list. It doesn't mean you can't display this list again in this application, okay? Save the changes and refresh the page and see the error is gone. That's how we map list in react. So congratulations. You successfully run the basic concepts of react. Now using these concepts, we are going to build our first project. I am very excited about this and hope you are too. So see you in the next section. 32. Section 04 Creating First Project in React: Welcome to the section four of the ultimate react course. In this section, we are going to create our first react application design in which we will see how the developer thinks before starting to develop the application and how to decide which components to create in our project. In this section, we will not add any functionality to our project. We will just focus on creating components and UIP. I'm really excited about this project and hope you are too, because this kind of project is great starting point for any beginners of react. So let's dive into this project. 33. Project Overview and Planning: First of all, let me give you a quick overview of this project called as task Track. It is a nice name, right? The basic goal of this application is to minus task. So this is how our application looks like when we have no task. After that, to add a task, we write the task in this input box. Then we select any tags we want, and also we can deselect them, and then by using this dropdown, select the task category to doing or done. And then we add task. And the moment we click on this at Task button, without refreshing the page, our task is displayed here. We can even add multiple tasks, and if we don't need them, then we can remove this individual task. So this is pretty good and nice project, which you can also add to your CV or portfolio. Now, before we start building any project, I personally like to plan the process of creating project. And with a plan, we can save a lot of time and effort. That's the secret why I create projects fast and without writing, use code. It is completely fine if you don't want to follow this process, or you can make your own process. So let me tell you how I think about creating the at project. First of all, we will create the SDML and CSS part of the application, which means how our application looks without any functionality. Now, after our design is ready, then we move to the functionality part, which means if we click on Ettask then the task will add in the sections or delete task, et cetera. Here also we can define some components. For example, here we have this tech design same for many places, and that's the one component. After that, we have the single card component. The skeleton of all cards are same. Just we have to change the details, and that's our another component. After that, we have the same design for these three sections. Same, we have to just change the data inside that, but the skeleton is the same, which is another component. So that's how we can guess the components for Rag project. But don't worry about that. We can also figure it out while building the design of our project. Just you have to find some design and we can make it as a component. Can see components by just looking at the design because I practice in so many react projects, and with practice, you will also do that. So don't worry about these things let's start building our first project. 34. Creating the website layout: So first of all, we will create the basic layout, or we can say skeleton of our application. So our web page is divided into two sections, the header and the main. And in the main section, we have three subsection. So let's create this layout. So back to VS code, and first of all, we will reset all the predefined CSS, all elements because we know some margin and padding are already added by the browser to some elements. We need to remove that. In the index dot CSS file, we remove all predefined styles and we add star for all elements inside this first, we set the margin to zero padding to zero. And box sizing to border box. These are all CSS concepts that I think you already know. Save this file, and after that, in the app dot JSX file, which is our root component, we remove all code, and we write RAFC for adding the boilerplate code. In app dot JSX file, we will add our applications components because this is the main entry point for the applications component hierarchy. Now, first of all, in this DU we add one header tag for our header selection. And give it a class name app underscore header. Remember, we have to use class name at the place of class. A, here I am using SNACCse for writing all CSS classes. You can use whatever you want to. After that, we add one main tag for our main section and pass class name to app underscore main. Now inside this main section, we want to add three sections. So we write a section and add class name task column, and we duplicate this score two more times. So in this die, we add here class name to app, and that's it. Now let's add CSS for this layout. At the top, we import codes periods for the current folder, and app dot CSS. This is a step almost all beginners or even experienced developers forgot to add. Before we add CSS to any components, please make sure we input that CSS file at the top of the component because without that, our CSS will not apply. Save this file, and now let's open the app dot CSS file. And let's remove all these tiles. We don't need this. And at the top, we at app, and inside it, we have to simply divide it into sections. So for that, we use cred so write display to grade and grade template rows because we want to define rows 150 pixel for header section and auto for main section. Save this file, and let's see what we get. Oh, sorry, we forgot to add our app component as root component. So in main JSX file at the place of this create to do we write app and also remove these both imports. We don't need it anymore. Save the inges and here we get just header because we didn't add anything in our main tag. So back to VS code. And in task column section, we had Section one. After that, section two. And section three. Save the changes and see, here we get these three sections in the main section. Now we want to display this task section one by one in column. So for that, we will use flax. In the app dot CSS file, we at app underscore main inside these, we write display flag for applyFlexbx, and also for setting this section in row. After that, we set justify content to space evenly to align these sections. And we also add some padding to 20 pixel for top bottom and 8% for right and left. Save the changes and take a look. See, here we get our section in center. Let's verify that using Inspect. So right click on this section and go to inspect. See here our section is in center. Now we want to make this section large enough so they cover the space. So we add new class task column and we define width to 333 3%. For now, let's add background color to tomato. And at last, we add some margin to 20 pixel. Save the changes and take a look. See here our section covers the width. Now in the next lesson, we will build our header form. 35. Creating Task Form Component: So as we know that react works on component based approach. And here, in our application, we didn't create any components. So let's start with our first component for our at task form. Before that, let's remove these both components. We don't need them. And we create a new component called taskfm JSX. Good. Now, tell me what we do first in component. Right. We had boilerplate by using RAFC. Now open app JSX file. Put this header tag and paste it into our task form component. Now at the place of this header text, first, we want to add form. And inside this form, first, we add input with type text and give it a class name to task underscore input, and also placeholder to enter your task. Now, after that, we have to add DV tag with class name to task underscore form, underscore bottom, underscore line. After that, we have to add a couple of tag buttons. So we add button with class name tag. And inside this, we pass HTML. Now let's duplicate this line three more times and we change this text to CSS. After that, Ja script. And react. I'm going a little faster for this designing and CSS part because this is our simple STML and CSS. I think you already know about that styles. I can give you all styles, but that is not fair because if you are working in react, you also have to write STML and CSS. So after that, we had select input for dropdown and add class name to task underscore status. And inside these, we add an option tag with the value to todo and display tags to todo. Second option value to doing, and pass here also doing. And third option value to done, and here also done. And at last, we add button with type submate class name to task underscore submate and we write here plus at task. Save this file. And now let's display this component in app component. So one app dot JSX file, and we simply add here angle bracket, task form, and C VS code auto suggests this component. Select this and press Enter or tab and see our component autoimported at the top. Now, make sure we close this component tag. Otherwise, we will get a compilation error. We can use here self closing element. Good, save the changes and take a look. See, here we get our form. Now in the next lesson, we add styles for this form component. 36. Adding styles for form component: I so let's add styles for this form component. So for adding styles, here we create a new file called taskform dot css. Now you might ask why we need to create separate file for this component? Can we add the styles in app dot CSS file? And the answer is yes. We can add styles in the app dot CSS file, and that's what some developers do, but that is not a right approach because currently we have only one component, but imagine if we have five to ten components and we add our all styles in same file, for changing the particular styles, we have to find the CSS in that single file, and that will be hard and also stressful. So that's why we define each component styles in separate CSS file. So let's first of all, import codes periods taskfm dot CSS. Save these and let's at styles in this file. First of all, we want to move this whole form at the center. We add app underscore header and inside this, first we set display two flags and align items to center, which will set our form vertically center and justify content to also center, which will set our form horizontally center. At last we add water bottom to one pixel solid has DC DC DC. Save this and take a look. C, our form is in the center. Now, let's add styles for this input box. So dot task underscore input. And in Gully brackets, font size to 20 pixel, font weight to 500, background color has F 9f9f9, color to black water to one pixel, solid and color to a DF E three, E six. After that, water radius to five pixel, padding to eight pixel and 12 pixel, margin bottom to 15 pixel, and width to 100%. Save this and see how input is ready. Now we want to make this form large. So here we add dot app underscore header, angle bracket, target form, and inside this, we set its width to let's say 40%. Save this and see our form width is good now. Now, let's set styles for the tags. But before that, we need to separate these tags with this drop down and add Task button. So in task form component, we wrap these all tags with Dv tag and we wrap another part with another div. Save this file, and in the taskfm CSS file, we add Task Form bottom line. And inside the cul brackets, we just add DF and C, it suggests display flags. These are small tricks which I learned with the experience of creating many applications. After that, we add align items to center and justify content to space between. Saw this and see our tags, and these two are separate. Now, let's set style for the tags. So we write tag and in cur brackets, first we add font size to 14 pixel font weight to 500, background color, two has F nine, F nine, F nine, border, one pixel, solid has DFE three, E six, border radius to five pixel, after that, adding two pixel for top bottom and ten pixel for left right, margin right to ten pixel and cursor to pointer. Save the genes and take a look. See, here we get our text styles. Now let's set CSS for drop down. So we do task underscore status. Inside this, we add font size to 16 pixel font weight to 500 wer to one pixel, solid has 999 Bader radius to five pixel. After that, width to 120 pixel height to 40 pixel and padding to zero and five pixel. Save this and see a drop down is also ready. Now, last style for this submit button. So back to VS code and write dot Task underscore submit. And inside this past one size to 16 pixel, one weight to 500, background color, two has 64 57f9. Color to white, which is has F, water radius to five pixel, height to 40 pixel. After that, padding to three pixel entertain pixel, margin left to ten pixel, border to none, and cursor to pointer. This is very basic styles. I don't want to waste your precious time by explaining these styles. If there are some important styles, then surely I will explain you that. Save the changes and take a here we zoom a little bit and see now our form looks pretty nice. Just one thing. I want to change this placeholder color because it looks a little dark. So back to aced. And after this input style, we add dot task underscore input, double colon, placeholder. And inside the culi brackets, we add color to a 686868. Save the chinges and take a look. See now it looks nice. 37. Creating Tag Component: So in the previous lesson, we create our form component, and in that component, we can see we have this button tag, which we are using multiple times. And also, when we create task card, we will also use that tag button. So it is better to store single tag in different component. So let's copy this single button tag. And in this component folder, we create a new component called tag dot Jx write RAFC for boilerplate. Now here, we simply piss that button. Now, as we create new component for this tag, let's also create separate file for its CSS. We create another file called tag dot css, and as we know, before writing CSS, we need to import it in this component. Import period tag dot CSS. Save this file. Good. Now open taskfmt CSS file. And we cut this text style from here, save this and paste it into our tag dot css file. Save this. Now, let's add this tag component in task component at the place of tag buttons. So we write angle bracket, tag, and select the auto suggestion. It will auto input tag component. Now, we can remove all these buttons and duplicate this tech component three more times. Save the changes and take a look. See, here we get this four STML tag button. Now you might ask, how can we change the button text? And that's the topic of next lesson. 38. Props in React: Now let's see how we can change the name of this tag button. So for that, we have concept of props in react. So first of all, what is props? Props stands for properties, and props are arguments passed into react components. In simple words, props are used to pass variable in react components. Let's see this practically. Now, first of all, let's close all files by right link on the file name and select close all. Now let's open our task form component. If you wonder how I am opening these files, so just press Control plus P or Command plus P and right here, file name which we want to open and hit Enter. See, without using mouse, we can open the files, and these are little productivity hacks which developers use. Now here we want to pass different tag name for this tag component. So here as we add attributes in SDML elements, here we can also add attributes in component. So we pass name equals to, and here we want to pass tag name. So we add codes, and inside these, we add SDML. Here, I want to clear one thing. We can give whatever name to this attribute. It's totally on us. For example, here we can pass tag name or anything. And by using this attribute name, we will access this value in that component. I know this is a little confusing, but don't worry watch this complete lesson and your all doubts feel clear. For now, let's comment out these other three tags, select them and press Control plus slash or Command plus slash. Here we pass our attribute. Now let's see how we can access this attribute value inside our component. Save this file and open tag dot JSX file. For accessing the props value, we can simply pass here props as parameter on this component function. This props is object, which contains all values of attribute which we set in tech component. So we simply console dot log props and add here props. Save the changes and take a look. Open up Console, and see, here we get this object, which have tag name property and its value. Now, let's print this value for our tag button. So here at the place of this HTML, we add curly brackets because we are writing JavaScript expression, and inside this, we write props dot tag Name. Save gangs and see, here we get SGML. Now let's add three other tags. So back to our component and we remove comment from the tags by using Control plus slash or Command plus slash. And here we pass tag name to CSS. After that, tag name to JavaScript, and at last tag name to Ra save the changes and take a look. See, here we get these tags with different tag name, and that's how we pass attributes for components. Let's quickly recap all about props. Props is a way to pass data from parent component to a child component. In our case, task form is our parent component and tag which is inside this parent component, we call it a child component, and we want to pass data from taskfm component to tag component. We simply pass attribute of tag name, and here we pass string value. But we can also pass arrays, objects, or even functions in the props. After that, for accessing the value of these props, we add props parameter in this component function and we get our data into this child component, simple as that. 39. Building Task List Component: Now let's build each output list column. Here we can see that in our design, these three columns to each other. Just we have to change the title of the column and Imoge. But the structure of all these columns are same. We can build component for the column and then reuse that component. That's how we need to think about when we are working on react because react is based on component structure. Let's create a new component called task Column dot JSX. Inside this, we add boilerplate and in app JSX file, we simply cut this task column section and paste it in our task column component. Now, first of all, in this column, we want to add title. So we create has to tag, and we write to do. Now, as we know, we have here image. So open up resources folder, and inside this, we have Assets folder. Now simply drag all images from this folder and drop it in our project assets folder. Now let's see how we can add image in react because it is a little different from what we do in SDML. So we add image tag into this ST tag, and here we cannot add relative image path. It will not work. So for adding any image, whether it is JPG, PNG, or even SVG, first, we need to import that image at the top. As we know, react use bundler like webpag to bundle all the code and assets which are used in the application. And when we input image file in our component, then bundler knows to include the image in the bundle. So that's why we need to import image. So we write at the top, Import todo from here we go one folder up assets and import direct dshit dot PNG. Now in this image source, we add calibracets and add our todo. Now you might ask what is inside this Studo? So this is nothing but just a path of our image which placed by bundle. Let me show you. So before return, we simply consult dot log this Studo save the changes and take a look. Oh, it looks mass. So first of all, let's remove this props Console. Open tag dot jsx file and remove this console dot log line. Save the changes and we get nothing because we need to add our task column component in our app component. Back to VS code and in our app component, we add task column component and see at Import works. Save the changes and take a look and see here we at the path of our image. Also, we can directly add URL in the source, but this is how we add local images in react. Now let's add style for this image and title. So in this image tag, we add class name to task column icon. And also, for this heading, we add class name to task column heading. Save this file, and let's create separate file for our task column styles called taskcolumn dot CSS. The reason why we always give it a same name as our component name because just by looking the file name, we can know this file contains CSS of this task column component. So let's first of all, import task column dot CSS file at the top of our component. Save this. And now let's add some CSS. So first of all, we want to make our image small. So we write task column icon. And inside this, we write width to 30 pixel margin write to five pixel. These and our icon looks perfect. But this text and icon is not vertically center. And also, let's remove this tomato background. We at Task column heading, and inside these Cully brackets, we add display two flags and align items to center. Save this, and let's remove that tomato background from app dot CSS file. So open that file and remove this background property. Save the changes and take a look. See now our title looks nice. Now, let's replace these two sections with our task column component. So head over to app dot GSX file and we remove these both sections. And simply add two more task column component. Say the changes and take a look. See, we get three section. Now, here is a little exercise for you. Simply, we need to change the title of these two columns. Don't worry about changing this image. Just try to change these headings. 40. Solution of this exercise: So I hope you solve this exercise. And if you can't solve this, then don't worry at least you try that. And that is the important thing. Now, let's see the solution of this exercise. So here, we have to use props because we want to pass data from parent component to child component. So we pass here props, title to Tudo second, title to doing and last title to done. Save this file and let's access these props in task column component. At this component function, we pass props as parameter, and we simply replace this todo with colli brackets and props dot title. So let's remove this console. We don't need that, save the changes and take a look. See, we get titles. So now I think you have clear understanding of how to use props. Now let's see how we can change these icons. For that, we also use props. Let me tell you the logic. First, we input all three images in this app component. We will pass that as a props. At the top, we first import to do icon from periods assets and direct heat dot PNG. After that, import doing icon from assets and glowing star dot PNG. At last we import De icon from assets and check mark button dot PNG. Now, let's pass these icons using props. Here we write icon equals and we use curly brackets. Can you tell me why write? Because we are writing JavaScript expression, and we pass to do icon. Similarly, con equals to doing Con after that, con equals to done icon. Save this file. And in the task column component at the place of this todo, we simply write props dot C. Save the gangs and take a look. See, here we get these icons. You can see how simple react is. At the beginning, almost all developers scared by react, even I scared from react. But with practicing and creating more application, we learn react fast. So don't worry about that. Just practice your skills, and with that, you will also master react. Here in our component, we can see whenever we want to access any props, we have to write here props dot title and props dot icon. But that looks a little bit ugly. So we can use object restructuring for that. So here we write cons object equals to props. And inside this object, we simply pass here our property names, title and icon. Or we can even simplify these by directly adding this object at the place of these props, this both works the same. So most common, we use this method, remove these lines, and also at the place of this props dot icon, we write icon, and also here, we write title. Save the changes, and it works the same as before. Now in the next lesson, we build our last UI part, which is task card. 41. Building TaskCard Component: So let's build a new component called Tascardt JSX. And also, we create a new CSS file called Tascard dot CSS. Now, in our task card component, let's add boilerplate for this component using RAFC and at the top, we simply import Taskcard CSS file. So we don't need to worry about that. Now, let's add elements for this card. So at the place of this DU, we can write article with class name task card. You can also use DU, but I like to use semantic tags. Now inside this, first we create one paragraph for adding task details and class name to task underscore text. And inside these, we simply write this is sample text. Now in the next line, we need text at the left side and delete button at the right side. So we create one due here with class name task card, bottom line. And inside this, we add two more DUO with class name, task card tags, and second, class name with task delete. Now in the first du we add our tech component, see what input does not work. So at the top, we input tech component from tag module. And let's add this component in our card. Now we simply pass here name props to let's say DML. Let's duplicate this tag and change name to CSS. Done. Now let's add image in this task delete. And for adding image at the top, we have to import image. Import, delete icon from go one folder up assets and delete dot PNG. And in the image source, we pass curly brackets, delete icon, and also class name to delete icon. Save this file, and now let's add this component into task column. So one of task column component. So here, after our heading, we add task card component, and C now to Import works. Save the changes and take a look. E, here we get our elements. Now, let's add styles for this card. So our card looks like real card. So in task card dot CSS file, we write task card. And in the cur brackets first we add width to 100% mean height to 100 pixel, border to one pixel, solid has DC DC. Next, border radius to ten pixel. Padding to 15 pixel and margin to 15 pixel for top and bottom and zero for left and right. After that, we had styles for text. So we write dot Task text. And in the cli packets, we had font size 18 pixel. Font weight to 600 margin bottom to 15 pixel. Save the ins and I don't see any difference because of this giant icon. So let's add styles for that. So we add task underscore delete. And inside this, we write width to 35 pixel height to 35 pixel. Water radius 100% for making it complete circle. Now we want to set delete icon at the center of this so we add display flags, align items to center, justify content, also center, cursor to pointer, and transition to 0.3 second is in and out. This is for adding little smooth animation. Now, let's add Hover effect for icon background. So dot task underscore DLate column, hover and we just want to change the background color two has IB, IB, Ib. Now, after that, let's make our icon small. So dot delete icon. And inside this, we add width 220 pixel. Save the changes and take a look. Fine. Now here we need to make these two divs in single line and place them left and right corner. So back to VS code, we add here dot task, card, bottom line. Inside this we write display to flags, align items to center and justify content to space between. Save this and see we get our card. Now let me show you one little trick which I used a lot. Currently, this delete icon looks too much dark. In the delete icon CSS, we add opacity to 50%. Also we add here transition all 0.3 second is in out. And after these, we add dot task, delt, call on hover, space, dot tilt, icon, and we make opacity to 80% because we want to increase this icon opacity when someone even hovers circle. Say the changes and take a look. See now our car looks nice. Now, from next section, we are starting to add functionality for this application, which is the main purpose of this course. I know I write little fast CSS, but that is because we are here for learning react. If in react course, we learn CSS, then some of you might don't like that. And also, I'm writing this CSS first because I practice this application before recording this course. So don't confuse by that. And if you are continuously watching this course, then please take ten to 15 minutes break and get some fresh air. I will see you in the next section. 42. Section 05 Adding Functionality in Project 1: Welcome to the Section five of the ultimate react course. In this section, we will complete our first project, which is Sask track application. We understand the basic of functionality, handling forms, selecting tags, and then adding task by their property, implement delete functionality, and also we will learn second most important hook of react, which is use effect. After completing this section, your confidence of creating react application will increase. I'm very excited about this and hope you are too. So let's dive into this section. 43. Handle Form: Now, before we start adding functionality in our application, first of all, let's understand the logic of this application. So here, first, we create array of tasks which have all task. Now, each task is the object with three properties. First, task itself after that, we have status of task, which can do, doing or done. And third, we have texts, which is the array of selected text. So when user add new task, we add new task object with these three properties, and then we will show them in task column, simple as that. So first of all, we are going to handle this form. Handling the form means here we have to get user input values like the text, task status, and selected text. If we don't have these details, then how can we store that details? So when a task form component, do you remember what we will use to get user input? Right, it is used State hook. Here at the top, we input usetateHok and inside our component, at the top, we create state variable called task and set task. As a default value, we pass here empty string. Now when something change in our input, we simply set that value in this task state. So here we pass event called on change. And inside this event, we have event object, error function, and here we simply call set task. Now as we know that whatever value we pass in this set task function, it will be the value of our task state, et target dot value. Now, let's verify we are getting our task or not. Simply console dot log this task. Save the genes and take a look, write something in this textbox and see we are getting the input value. Now at the place of writing this expression here, we can write it in separate function. So we pass here, function name, handle task change. And inside this, we pass this event object. Now, let's define this function. So const handle task change equals to here we get our event object, which we pass from here, arrow function, and inside this, we set task to event target dot value. Save the changes and see, it works the same as before. We can write this code in both method. Now here, we can even make this code shorter. At the place of this expression in react, we can directly pass our function name, which is handle task change. This both works the same. But remember, we have to use here arrow function syntax. Otherwise, this will not get event object. We get the value of our input. Now let's see how we can get value of this drop down. So as we do for this input, same we do with that drop down. So first of all, we create one more state variable for storing the value of current state. So we state and pass here status and set status and as a default value, we pass here to do because by default, if users don't select any value, then we add status to to do. Now in this select tag, we add here event called on change. And inside this, we pass new function reference, handle status change. Now, let's also define this function. We can also duplicate this function, and at the place of this name, we write our new function name, handle status change. And at the place of this set task, we write set status, and that's it. Let's verify that works or not. So here we also add status in the console, save the changes and take a look, write something, and we can see by default, we get to do as status. Now, let's change value from drop down and see here we get that value. So it's working. Now here is a one problem. As we can see for each value, we have to create here state variables and also we have to define separate function for handle change, and that's a lot work. You might ask, is there any shortcut trick for that? The answer is yes. There is one little trick which we see in the next lesson. 44. Shortcut trick to handle form: So currently in our form, we have only two form fills. But imagine if we have five to six fills, and you create state variable for each input, and that makes our code messy and hard to manage. So let's see how to handle multiple inputs using single on change function. In previous lesson, we create individual state variables for form fills. And then in each handle change function, we set that value to our state variable. But in this method, we create only one state variable for all input fills. Let me show you. Let's comment out this code, and at the top, we create a new state variable called task data and set task data. And now as default value, we pass here object. And in that object, we have multiple properties in key value pair. So we add task to empty string and status to todo. Now let's create a new function, handle change equals to error function. And we will call this function on every inputs on change event. So in our input field, we write here handle change. Now let's simply copy this change event and paste it in our select tag. So whenever we type or change the value in any of these fields, only this handle change function will run. Now, most important step and without this step, this method will not work. So the step is we have to add all properties as its name attribute from our state object. Let me show you what I mean. So for our task input, we want to store its input value in this task property. So in our input tag, we add here name attribute equals to task. Now for our status drop down, we want to set its value in this status property. So we add in this select field name attribute to status. Make sure we write the same name as we write in the task data object. Now, inside this handle change function, we write our main logic. So here we pass this E as event object for all these fills, and let's simply console dot log this E dot target. Save the changes and take a look. See, when we type in task input, we get this task input, and when we select value from dropdown, we get that select tag. Our main logic is when we type in form field, first we get that field name and value and with that name, which will be the same as our task data property, we replace its value by current value. I know this sounds little complicated, but it's not. Let's see this and after that, your all outs feel clear. We create here name variable equals to e dot target dot Name. And we create another variable value equals to e dot target dot Value. And let's console both these variables. Say the changes and take a look. See, we get fill name and its value when we type in the input fills. Now, we just have to set this value inside our state variable related to its property name. So we write here set task data, and we get here previous values by this previous parameter. This previous value is same as our current task data value. Now in this arrow function, we return object First of all, we return all previous value using spread operator. Now we only need to update field with its value. So whatever we return from this callback function, that will be the value of our state variable. Now here we know we can access object property by using square bracket and pass this name variable inside eight and Colm its value. Now if we write anything inside task input, then first, this will return all previous properties, and then we find property task and replace its value with the task filled value. Simple as that. Let's Consult dot log this task data variable and see if we get values or not. Save the ginges and take a look. E, when we update any field, we get its value in our state object, so it's working. Now we can make this code even shorter by using object restructuring. So we write e dot target, and by using Object restructuring we fetch a name and value variable. So these two lines are same as this one line code. So we remove these two lines. Now we want to console this task data object when we click on At task submit button. So we create here a new function called handle submit. And inside this function, we simply move this console. Now in the form tag, we pass on submit event and we pass here handle submit function. Now you might ask, can we pass that function in onclick event of this button? And the answer is yes. You can also pass this function on on click event. But why we pass that function in on submit? The reason is when someone writing in the input box and then press Enter and also when someone click on Submit button, in both cases, this handle submit function will run. We only pass that function in tlk event, then it will only work on button click Save the changes and take a look, write some task. And select the drop down value and click consummate. See, for just a second, we get the value, but after that, our page gets refreshed because it's the default behavior of form. So whenever we submit the form, this handle submit function will run and then it refresh the page. We have to stop this. So we adhere this E as event object. And write E prevent Default. This function will prevent form default behavior. Save the changes and take a look. Fill this form and see here we get these details. Let's quickly recap this trick. First of all, at the place of creating multiple use state, we create single state variable, which is object. And in that object, we will add properties name and the default value. Now forgetting the form field name, we will pass name property exact same as this object properties name. After that, we will pass one single function for all form fields on changed event. Inside this function, first, we get name and value attribute from event object, and then we replace the current value of our task data object, simple as that. That's how we manage multiple form fields in react using shortcut method. You can see just by using two lines of code, we can set values in our object. 45. React Strict Mode: Now, let me show you something interesting. We simply here duplicate disconsol task data and move it outside in our component. Now one of the most arising questions which all react beginners ask me is when we do console dot log, why we are seeing all data twice? Should we did something wrong? And when I was learning react first time, I also asked the same question. The answer is no. You are not doing anything wrong. It is happening because of react mode. In our project, open up main JSX file. Here we can see react wrap our application with this react stric mode component. For now, let's comment out this ric mode component. Save the changes and take a look and see here we get our data one time. So it's firm. That is because of react street mode. But why we need this street mode. So react Street Mode is a tool provided by react that helps developers write better quality code by highlighting the potential problems during development. When we wrap our application with react dot Street Mode, it activates additional checks and warnings that will help you to identify issue before they cause problem in production. For example, it will check for not supported or deprecated react APIs and components, save straight updates, potentially unnecessary re renders, and that's why it render our application twice. So it's better to enable street mode for our application. Let's remove these commands and enable street mode for our application. Save the changes and take a look. See, again, we get two data objects. So I react 18, street mode is by default turned on and react renders each component twice. So that's how strict mode works in the development process. When we deploy our application for production, the street mode will not added and that will render our components only once. So don't worry about that. Let's also remove our Consult log line. In the next lesson, we will see implementation of tax selection. 46. Tag Selection: Now let's implement the tag selection functionality. But before that, let's remove this comment out code. Now, in our task data variable, we add another property called tags and pass empty array as default value. When we select any tag, we will add that tag into this array. And if that tag is already in this array, then we will remove that tag simple as that. And this is my trick to implement any logic in programming. Should I give you this trick, let me give you. The trick is, whenever we want to add any functionality, describe that functionality in human language, and that's it. That's how you can crack the logic of any functionality. So first of all, here we create a new function called select tag, error function, and this function will run when we click on any of the tag. So we have to pass function inside this tag component. Can we do that? By using props. Here, we simply pass props called select tag and pass here our function name which is select tag. Here we are using the same property name as our function name because we don't need to worry about giving the new name. You can write here any name. It's totally up to you. Now, let's copy this and paste it for all tag components. Save this, now let's open this tag component. And here at the prop, we can destructure object and get here tag name and Celac tag. Now, let's remove these props and also here we pass on click event and we simply pass the Celac tag here. And that's it. Our SeLlactag function will run on this Estag click. Now let's write our logic for sectag function. First of all, question is, how can we get the current selected tag? Because without knowing the tag name, how can we write any logic? So in the tech component, we can pass this tag name as argument of this select tech function. But we can't call this function here because then our function will run only once. So for solving that issue, we can pass here error of function and inside this, we can call the selecteg function and pass tag name as argument. Save this file and in the task form component, we get here tag as parameter, and simply consult log this tag, save the Gengs and take a look. See, when we click on this tag button, we get this tag name. But our form also gets submitted because we are getting the task data object here. See? So let's solve that. So open up tag component. We have to simply pass here button type to button. Because in all browsers, except Internet Explorer, default type of button is submit, and that's why our form gets submitted. Save these and see, now we only get tag name. Now our next task is we want to store this tag into text array. So in Seat tag function, first of all, we write if condition, and here we want to check. Our tag is already available in tax array or not. So we write task data dot tags. Now here we use some method, and inside it, we get here each item, arrow function, and we have to pass here condition, item is equal to Eg. Explain you this expression. The sum method will return true or false value. We are checking here each item of our task data dot tags array, and here we compare it with a tag name. For example, we select STML tag, then this expression will check each value of these tags, and if STML is available in that array, then it will return true, otherwise false, simple as that. What we will do if tag is already available, we will remove that tag from that array. So we write task data dot text, dot Filter. Now, also in this, we get each item arrow function, and we pass here condition, item not equals to tag. Now, as we know, this filter method will get items which will pass this condition and return a new array. So we store that in variable called filter tags. Now we have to update our text value by this new filter tags. So we write set task data. First we get here previous value, error function, and inside it, we return here object, and first, we add all previous values using spread operator. And we simply overwrite tags to filter tags. Now we add Ls condition, which means our tag is not available in this text array, we can directly add that tag in our array. We write set task data inside this, we get previous value, arrow function, and here we return object, and here we add all previous values using spread operator. Because without that, our task and status will also get replaced. After that, we overwrite tags and here we pass our current tag. Now let's see if this works or not. So simply console dot log, tagdata dot tex, save the changes and take a look. Select any tag and see we get that tag here. Now, again, click on that tag. Se it's gone. Now here is a one bug. Select one tag and then select another tag. You can see our previous tag is gone. So why this is happening, let's find that. So here in's condition, we directly replace tags value with the current tag, and that's why our old tag we replaced by new tag. Here, we also use spread operator previous dot tags, which has all old tags and simply add new tag at the end. I intentionally do this mistake because I want to show you the importance of these previous values. Save the changes and take a look. Select the tags and see it's working. 47. Display selected tag on UI: Now, when we select our tag, we can't show any effect on our page, and that's the bad user experience. So to display the selected tag, we only need to check whether that tag is available in our tag array or not. Here we create a new function called Jack tag arrow function. Now inside this, we simply want to return true or false for the tag. Do you remember which method we used to check? We have already done that in the Sylac tag function, which is using some method. We simply return here task data dot tags dots. Inside it, we get each item arrow function and we check item is equal to our tag, and we get that tag from the parameter. Now we pass this true and false value for each tag. So scroll to the tech component. We pass here one more props called selected, and here we call check tag function. And inside this, we pass our tag name in double codes. Note that we write the same name as we pass in tag name. Save this file, and in the tech component, we get here selected props. Now using these selected probs, we can add selected effect. Here, we will use inline styles because we want to set different color for the SDML CSS, JavaScript and react tag. For that, we create one variable called tag style and we declare that as object and inside this object, we at key value pair. Let me show you. First, we pass SDML and here as a value, we pass object with background color property. And value to a FD a 821. Now you might ask why we add here object. The reason is we know that in inline styles, we have to pass style object. So we can directly add this object by tag name. Now, let's add styles for other tags. Duplicate this key value pair four more times, and here we add CSS and change background color to a 15 d4c8. Now for JavaScript, we change background color two has FF D one, two C, and for react background color, two has for C, DA FC. Note that we the same name of tag that we pass in the tag name props. Otherwise, it will not work. Now you might think why we add one more key value pair. This last one for the default background for no selected tags. So we add default background color to has F 9f9f9. Now, let's add styles according to conditions. We add here style equals to Coli brackets because we are adding Javascript expression, which is if selected is true, we add the textyle textile and in a square bracket, we pass tag name. Else, we add textile dot default. Simple as that. Save the changes and take a look. See, when we select the tag, its background color will change and after that, back to normal. Now with other tags, we don't see these styles because we didn't pass selected props for them. So back to task form component, here we select the selected props and copy it from here and paste it here, and we change tag name to CSS. Now, same as we do for JavaScript, and also we do the same for react. See the changes and take a look. See now our tags have this selected effect. I know this inline style object is confusing you. But if you revise this code, you will understand that properly. After that, you will see how simple it is to implement this selecting functionality. Just you have to think in day to day language and you are don't search for everything on Google. If you try something and stock, then use that as a tool. Now, here we have all details about task in this task data variable. So in the next lesson, we will see how can we display that task in our section? 48. Displaying the Task Cards: Now, let's add our main functionality of this application, which is adding task. Without that feature, our application is not useful. So here we are going to store all our task in single array, and by using the status property, we will display them in each section. We make that array as a state variable because when we add the task or delete the task, we want to see the changes on our dome. Now the question is, in which part of our application we need that array. First of all, we need to access that array set function in our task form component because when we submit our task, we want to add that in this array. And after that, we need to display that array state in this task column component. So we need the task array in these two components, taskfm and task column. So we have to create that state variable in this app component. So we can pass that as a props in these two components. So at the top, we import use state from react library. And in the component, we write us State and pass variable name, task, and set task. And we pass mt array as a default value. Now, let's pass this set task function as a props in this task form component. This file and hold control or command and just click on the component name. It will lead us to that component file. Now here at the parameter, we destructure props. I know in this component, we don't need that, but that is a good practice which helps us in future. So here we get set task, and in the handle submit function, we will set our task data in the set task function. So at the bottom, we write set task. Now here also, we get first previous values, arrow function and return here array, and first we add all previous values using spread operator. And after that, we simply add task data object, and that's it. Now, let's zoom out a little bit my VS code with Control and minus or Command and minus. Save this file, and let's verify what we get. So back to app dot JSX file and simply console dot log Tasktask save the changes and take a look. Write this and we can see we are getting text array. So let's clean this console. Open task form component, and here we remove this console text line. Save this and let's refresh the page. This is task burn, we select tags, and we select status to doing and click on Attask. See, here we get this task. Now, let's add one more task. Tags status to do a task. See, I get that also. So that's working. Now, let's display those task in this column. In app component here in this task column component, we pass first task as props, and after that, we have to filter those task by status. For example, if status is doing, then we only display task which status is doing. So we pass here status equals to to. Now let's copy these both props and pass here in this task column. And we simply change status to doing and here also, we paste these props and change status to done. Save these. Now in the task column component, we simply destructure here task and status. Now at the place of this static task card, we adhere calibraket task dot Map. Here we get each task and also index, and we simply add here condition, task dot status is equal to this status and puritan task component and inside it, we pass key attribute for each unique item, which is our index. This end end operator will only for true expression. So only if this condition is true, then we return this task card component. Otherwise, we don't get anything, save the changes and take a look. See, here we get two cards. One in to do and one in doing. Now we have to only change these details inside this card. So for displaying these details in our card component, we have to pass them using props. So here we at title equals to task dot Task. After that, tags equals to task dot text. Save this file. And now let's display these two values in our card. So in card component, we destructure props here and get title and tags. Now, at the place of this text, we write title, and at the place of this text, we at Cul brackets and text dot Map method. Here we get each tag and also index for passing it into Key. O function, and we return here tag component, and we pass key to index and tag name to tag. Save the changes and take a look. See, here we get these details and tags. Now, last thing, we want to show colorful tags. So do you remember we have selected property? And by that, we can add colorful tags. Let me show you. So here we pass just selected equals to true, and that's it. Save the changes and take a look. See now our card looks really good. Also, if we want to pass any props value to true all the time, we can write only that prop name. Same as we write disable attribute in HTML. Save this and see it works the same as before. 49. Deleting Single Task: Now, before we start implementing delete functionality, let's fix this little thing in our form. So when we add our task, these old details are still here. So if user want to add another tag, then they have to first disect the tags, and that's not a good user experience. So when you create website for any client, you have to also thought yourself as the user of that application and figure out what problems or bugs are available in your application. In task form component, we want to reset this form after we set our task data in the set task function. Basically, we are resetting this task data object to the default value. So we write set task data, and inside this, we simply copy this default object and paste it here, and that's it. Say the changes and take a look. Submit the form and see our text get reset, but this text box and this drop down is still same. Why is that happen? Let's find this out. So here, in this input element, we are not linking the value of our task to this input value. Let me show you what I mean. So here, when something we change in this input, that input value will add in our task data dot task property. But when we change our task data dot task property, then how react will change the input value. We didn't do anything for that. Don't worry. This is very simple. For that, we simply add here value attribute and in CL brackets, task data dot task. Also, in this select, we pass value attribute equals to task data dot status. That's why we need to add value property so it works both way. Save the changes and take a look. Write task select tag and also select status and submit the form and see our form gets reset properly. Now, let's see how we can delete task from here. So back to our app component, here we create function, which will handle delete functionality. Now, how can we delete a specific task? So here we know each task element has its unique index. So we pass here task index. Now inside these, we use filter method, so task dot Filter, here we get each task, and in second parameter, index error function, and here we pass our condition. We want to only take that task, which index is not equal to task index. Now we know that this filter method returns a new array. So we simply store that in variable called new task. And after that, we set this new task in set task function. Our delete function is ready, we have to only make that function run on our delete click event. So we pass new props in these three task column components, click here and hold alt or option and click here and here. That will create multiple cursor, and we simply write here, handle delete equals to handle delete. And press Escape. Save this file and now open this task column component, and here we get handle delete props and simply pass that in this task card component. Handle delay equals to handle delete. And also we pass index equals to index because we need to pass that index in this handle delete function. And we can see that here we are passing nested probs, which is this handle delete function. Save this file, and now in the task card component in the probs, we get handle delete and index. Now in this DU, we pass here event called on click. And here we pass handle it function. Now we have to pass index value in this handle it function. Otherwise, our dite functionality will not work. So how can we do that? Right, we simply pass here arrow function, save the changes, and take a look. Click on Delete icon and you can see how smooth that task gone. So that's how simple to implement delete functionality. Now, here you might have a question why we create delete function in our app component. We can create that in task component. Yes, we can also create handle delete function in task card component. But here you can see this handle Delit function need task date and also set task function. We create handle delete function in task card component, then we have to pass this task and set task both as the props, and if we create handle delat in app component, which have both variables, then we have to pass only the handle t function as props. So that's the reason. 50. Basics of useEffect hook: So let's first understand what is use effect. Use effect is used to perform side effects in our component. So what are side effects? Side effects are actions which are performed with the outside world. We perform a side effect when we need to reach outside of our react components to do something. For example, fetching data from API directly updates the dome in which we use document or Window object or timer function like set timeout or set interval. These are the most common side effects in react. So to perform any kind of side effects, we need to use use effect hook. Don't worry about this theory. Let's say this practically. So to use any hook, we need to first input that hook from react library. So we write here use effect, and now we can use it in the function component. We call us effect hook, which accepts two arguments. First, callback function, which is a function in which we write our side effect logic. This function will execute whenever something change in this whole component. And second argument is dependencies, which is an array of variables, and it's an optional argument. In simple terms, the first argument is what to run and the second one is when to run. Use effect runs on every render, which means when the count changes, or ender happens, which triggers another effect. But we can control that by dependencies. If you are familiar with class components, use effect is the combination of component did mount, component did update, and component did unmount. Use effect has three variations. Don't worry. We will see each variation in details in upcoming section. But currently, let me tell you in very short. So first one, use effect without any dependencies. So if we don't pass any dependencies, this callback function will run every single time when something changes in our component. Second, use effect with empty array. So if we only pass an empty array, this callback function will run only one time when our components get surrender for time. And third, use effect with variables. So for example, if we pass a task variable, so when this task state change, only then this callback function run, and that's what we want to do here. Inside this callback function, we write local storage dot set item. Now at the first parameter, we pass our variable name which is task. And at the second parameter, we pass our task array. But here, we have to convert this array into string format because local storage can only store strings as values. If we store directly array as a value, then it will automatically convert it into string, but then we can't access that letter as an array. So we use here Json dot string UPI method. And pass our task array here. This function will also convert our array in the string format. The only difference is we can convert that string into array again and use it, save the changes and take a look, submit one task, and we get the task here. Now, let's see it is also storing in local storage or not. Open up local storage, and here we see our new task. Now if we add another task, see our local storage gets updated. Now, as we know, we store our array in string. So when we get that array, we have to convert that back in array. So back to our app component and at the place of this empty array, we pass json dot pars, and inside this, we pass this old task value. This function will convert our string in array. Save the changes and refresh the page. See, we don't lose our task, delete one task and also try to refresh the page. See, we also get updated task, so it's working properly. Now, here is one little bug. Open up local storage, and if we delete this task array from here, and after that, we refresh this page. See, here we get this error because we can't find task in local storage. So to solve that, we pass here or operator. Here empty array. If this expression returns null, then it takes an empty array as the default value. Save the ings and take a look. Now our application works well. 51. Adding custom fonts: Now our project is almost done. I add here some task for demo. Now we just need to change our font styles for our application. So there are two most popular ways to add fonts in react application. First one is we have offline font file in our system, and also we can use CD and Link for adding fonts. Let's see the easiest way, which is using CD and Link. We will see offline method later in this course. Don't worry about that. So in this project, we are going to add Montserrat font. So head out to Browser, open a new tab, and search once you're at Google font. Open this post link. Now on this website, we get lots of font for free. Also, we have another website, Font Squirrel. You can use whatever you want to. It's totally depends on you. Here, we can select different font styles which we want to use. So select 400, 500, 600, 708 hundred. Now in this section, we have option, simply select Import section and copy this import statement and in our index dot CSS file at the top, we paste this CD and Link. Good. Now back to browser again and scroll down and copy this CSS for this font family. And in our index dot CSS file, we add here styles for body, and inside it, we paste our font family. Save this file and see, we get our styles and fonts. Now our application looks really amazing. 52. Wrapping up Project 01: Congratulations. You successfully complete your first project in react. I know you learn a lot from this, and also you can see it is not really hard to build application in react. It is really simple. You have to learn the functionality and features of react. Don't worry about learning all concepts in one go because that will overwhelm you. So learn some features and practice it, then again, learn some features and again practice it. Practice is the key to success, and that should our main focus. You want to practice this complete project again, then you can do that. That way you can learn more about react, and if you are comfortable to move forward, then you can continue this course. It's totally up to you. Different people like different approaches. Thank you so much for building this project. I know your confidence about react is increased, see you in the next section. 53. [Optional] Drag and Drop feature in React: Dragon ropFeature is very useful feature to give more flexibility to your website users, and also it looks so cool. We can move this task card up and down in the same task status, or we can also change status, which can be doing or done. So in this tutorial, we will see how to implement Dragon rob feature in react. Are many libraries for that, but I'm not a big fan of using those libraries. Instead, we can create Dragon rob feature using drop events of SDMLPi. It is very simple. Don't worry about that. Watch this complete tutorial and your all doubts feel clear. So without wasting time, let's start implementing Dragon drop feature in this react to do application. So let me ask you one thing. What is happening in Dragon rob feature. Don't think about writing code, think about how Dragon rob happen in real life. We are grabbing one thing and place it at some other place. Simple. Suppose we have list of task and we divide them in two categories to do and doing, and we also arrange them in order of priority, which means which task we want to do first, and then second, third, et cetera, and also we can do multiple tasks at the same time. Now suppose we want to move the second to do task to the doing list, but at the second priority. Other details we need here. Think about it. So the first thing we need is which task we are moving. Also, we need in which category we are putting that task to do or doing. Also, we need at which position we are placing that task. In this case, that is second. And that's it, we simply move this task to this category and position, simple as that. In this application, we have three categories, but dragon rob feature will stay the same. So I divided dragon rob feature in three steps. First, we should know which card we are moving. Second, we create dropping area where we can place our card because we don't want to place our card all over our application, so we will create dropping area for that. And last part, write function for drop task to position and change the status if we move to another status. Let's start with step number one, know which card we are moving. Currently, in our application, our card is not draggable. First and foremost, we have to make them draggable. So in this application, for each column, I created this task column component which we reuse, and for each task card, we have task card component. So we have to make this task card component trackable. Now to make our task card trackable, we have SML phi attribute trackable to true or we can only write trackable. Save this, and now we can see now we can move our task card component. Now here we want to know which card we are moving. So we need something unique for each card like task ID, but we don't have ID in our task list. Don't worry. We can also use here this index, which is also unique for each task. Now to store that dragging card index, have to create local state variable because we can select any card, and our dragging card value will also change. Now the question is where we create that tragable state variable, where we need gable card state. So in our app component, we have our task state, and also in app component, we need gable card index, so we can modify our current task list. So after this task state, we create a new state variable called active card set active card. As a default value, we set it to null, which means no card is dragging. Now, when we start dragging any card, we store that card index value in this active card state. And when drag will end, we again make this active card value to null. Now to set active card to this task card index, we need set active card function in task card component, and how we can do that. Right by using props. So back to app component, we move our cursor to here, hold Alt or option, and also click for these two task column components. By holding Alt or option, we can create multiple cursors. We pass new prop, set active card equals to set active card. Press escape for exit multi cursor editing. Save this and in the task column component, first, we get stactive card in props and also pass it in the task card component, Stective card equals to catective card. Save this, and in the task card component, finally, we get cetactive card function. Now in the article tag or if you have due then in that tag, SDMLPi ddt tag events. Here we need on drag start because when we start dragging this task card that time we set active card to the current card index, which is this index. So arrow function and simply setctive card to index. Also, when our drag is over, we want to set null to active card. So we add another event on drag arrow function, set active card to null. Save the changes. And for tasting, let's print active card. In app component at the bottom of main tag, we add H one tag and simply print here active card. Save the changes and take a look. Drag one card. See here we get the index of the task, and the moment we drop our card, see, it's gone. Now here when we are dragging our task card, we can highlight our selected card for better user experience. So in the task card dot CSS file, after the task card style, we add task card, colon active and inside this, we first set opacity to 0.7 and border to one pixel, solid has 111, which is black. And also for task card, we set cursor to grab. Save this and see now we get these tiles. So our first step is done. Now the second step, which is creating dropping area means where we can drop our active card. We can rag our card at two places. After each card or before our task list, which is the place between this task status heading and list first task. So these are the places where we can place any card. So when we drag our card at that place, we can show something like drop here or simple box. Let me show you how to create that. It is really simple. So in our component folder, we create a new component called drop area dot JSX. We are creating separate component for showing dropping area because we can use that same component multiple times. Here we add boilerplate code using RAFC at the place of this due, we can add section tag, and here we write drop here text. Save this, and let's display this dropping area component after each card. So here, in the task column component, here we can see we are mapping all task in the column. So after this task card component, we add our dropping area component. Now here we get runtime error because here we are returning to components. So to solve these, we can wrap both components with react dot fragment. And move this closing fragment after dropping area component. And here, we have to pass key equals to index in react dot fragment because here we are mapping list. See the changes and take a look. See, after each task card, we get drop here component. Now we also need this drop area component here at the top of list. So back to VS code. Here before this task map, we add drop area. Save the changes and take a look. See, here we get this drop area. Let's make these styles a little better because here I think it is margin issue. So open task column dot Cssle and for this heading, add margin bottom to 15 pixel, save this, and also in Tascard CSS file. Instead of this margin, we set margin bottom to 15 pixel. Save this, and now it looks little nice. Now we will style this dropping area section. So back to dropping area component here, we give this component class name to drop underscore area. Now for CSS, I like to create a separate CSS file, drop area dot CSS. Here we had drop area and inside this width 200% height to 100 pixel, color to has DC DC DC, border to one pixel has DC DC DC, wer radius to ten pixel, padding, 15 pixel and margin bottom, also 15 pixel. Now to apply these tiles to our drop area component, we need to import this file at the top. So import dot slash drop area dot css. This one thing I forgot a lot when I started learning react. Save the changes and take a look. See, this is how it looks. Now by default, we don't want to show this dropping area. We want to only show when we drag our task card on dropping area. For that, we need to create one local state variable in drop area component. So state and give it a name, show drop, set, show drop, and by default, we make its value to falls. Now, the simple logic is when we drag our card on this section, then we make this state to true. And when we drag from this section, we will make the state to falls, which means don't show. So in section tag, we have another event called on drag Enter arrow function and set show drop to True. And we add another event on drag Liu arrow function and simply call set showdrop to what we falls. Also, for this class name, we can add condition. So here, we add C brackets. If showdrop is true, then we add drop area class, else we add hide underscore drop class. Save the changes, and in the drop area dot CSS file, have to add some more styles. So in drop area, we add opacity to one and also transition to all 0.2 second is in and out. And at the bottom dot Hyde underscore top, we simply set opacity to zero. So the changes and take a look. Drag one card and simply over one dropping area. See how beautiful this looks. So here our second step is also done. Now we just need to know on which position we are dropping our card. And then, according to that, we write function for updating our task list. Now, first, how can we know in which column we are dropping the task? So in the task column, I previously passed status, so we can use that status, and also forgetting the position we have here index. So if you want to add our task next to this task, then our new index will be index plus one. Don't get confused. I will show you in just a minute. So in the app component, we create a new function called on drop. And in the parameter, we get status, which is in which column, we are dropping our task. And also, we will get index, or we can say position, which is the position of dropping task. For now, I simply Consol dot log Ti dollar active card is going to place into dollar status and at the position dollar index. The place of index, I'd like to give this parameter name to position. I think that is more accurate. Now we have to call this function when we drop our card in dropping area because that's when we want to make changes in our task. So we pass this function as props in these three task columns. I think by mistake, I give on writ function name. Select this and press F two and rename the function name. Save this file, in the task column component, first, we get on drop as props and we simply pass that on drop function as props in this drop area component. Also, for on drop function, we have to pass status equals to status. A we need index, which is index plus one because we want to place that card after this task card. Now instead of passing these three probs, we can do something like this. In the on drop props, we can pass callback function and we simply call here on drop function. And first parameter, we pass status, which is this task column status. And then we pass index plus one. If you get confused in this method, then you can separately pass three props, and in the drop area component, you have to call simply like this. Let's save this file, and in the drop area component, we get on drop function. Now, in this section, we have another event called on drop, which will run when we drop something into this section. So here we pass callback function, and first, we simply call this on drop function without parameter because we already pass that parameter in previous props. And also here we have to hide the drop area after we drop the card. So set should drop to falls. Save this. And if we do drag and drop into any drop area, we don't get or console message because we have to prevent the default behavior of on drag over event. We add here on drag over, we get here event error function, event dot prevent default. Save this, and now if we again drag and drop the task, then we get our console message, which one is going to play into doing at the position three, because this first card index can be two, but it doesn't matter. So we are getting our needed data and also position. Now if we drag and drop our card at the very beginning of the list, here we get error. On drop is not function because we don't pass on drop function as props in this drop area. So I simply copy these on drop props from the bottom and simply paste it here. Now, can you tell me which property we need to change here? Right, we just need to change the index because status is going to be the same. So at which position this dropping area is? Simply, it is at zero because in array, zero index is the first position. Here's the changes and take a look. Now we get the console message, we have active card status and position. Now we just need to write logic for rearranging our task in on drop function. First of all, we check condition if active card equals to null or active card equals to undefined. Then we simply return from this point. After that, let's simply pick task, we want to move. So const task to move equals to task, and we get active guard. After that, to update our task list, first, we have to remove the current tective card from our task list. Task dot Filter, here we get each task and also we get the index arrow function, and here we pass condition index not equals to active card. This filter method will remove our current active card from this task list and return updated task array. So we can store that array in the variable called updated task. Now we just have to place our task to move at our dropped position. So we can use a splice method like this, updated task dot splice. Now at the first parameter, we write where we want to place our new item. In our case, it is stored in position. After that, we write zero, which basically means zero elements removed. And at the third parameter, we can pass our object or item, which we want to store at this position. So I add here object, and first of all, I spread all properties from task to move object, and after that, we can simply change the status property to this parameter status. Now, as we know, we have updated task list, so we can simply set task to updated task. Also, from the bottom, let's remove this h one tag, which is displaying active card. Save the changes and take a look. See, now we can move our task from one list to another, and also we can move them in simple list. So that's it for this tutorial. This is a long tutorial, but I hope you see Dragon drop is not that much difficult. We have to do step by step process. 54. Section 06 Project 02 - MovieManiac: Welcome to the Section six of the ultimate React course. In this section, we are going to start building our project too, which is movie Maniac. You can see how cool it looks and the movie details are coming from another website. We can also filter these movies by its rating, and after that, we can also sort it by release date or rating, ascending and descending. The goal of this project is to learn EPI calling, filtering features, and sorting features which are used in lots of real world applications. Know you are excited about this project, so let's dive into this project. 55. Setting up project & Layout style: Let's start with creating the new project. So open up your react project folder and open command prompt or terminal in that folder. Now, can you tell me which command we will use to create new application? Write NPM, create white, aerate, latest, and hit Enter. Now here we write our project name movie Maniac, and press Enter. Now, select the framework, which is react, and after that, select variant, which is JavaScript and hit Enter. Now we only need to run these three commands. So first of all, go into this folder with CD and press tab, select movie Maniac folder. Now let's install all dependencies. So NPM install, and hit Enter. It will take some time. So till then, let's plan our application. So first of all, we can divide our application layout into two sections. First one is Nevar and second one is this movie list. Now, let's define components we can create for this application. One thing I want to clear that this planning process is not the absolute plan. It is just a quick starting point. We can add or remove components depending on our needs. So first, we can separate this Naba component. After that, we can create component for this movie card. After that, in this display section, we have three more section, which are the popular top rated and upcoming section. But you can see basic structure of all the section are same. All have headings, filters, shorting, and list of movie cards. So we can also create reusable component for that, and I think that's all we need. Now let's check our dependencies installed or not. And yes, it is installed. So let's open this project in VS code by code space dot, and hit Enter. Good. Now we can close this terminal. We don't need it. And also, we close our folder. Now, let's make sure our project is working or not. So open up terminal by Control plus Batak or Command plus Batak and write NPM run DO and hit Ender. One more thing, if you want to stop this application, press Control plus C or Command plus C for that. Now hold Control or command and click on this local host URL. And it's working. Now, let's create basic layout for our application. So open app dot JSX file, and we remove all code from here and create functional component with RAF CE. Now, first of all, we give this class name equals to app. And inside this Du we want to create first NaBr we write here Naw tag and give it a class name Na Bar here we write Navbar content. After that, we create our main section of our application, and inside these, we simply write main content. Save these and let's see what we get. See, here we get both section. Now, let's set style for each of them. But before that, we need to remove some basic styles. In index dot CSS file, we remove all styles, and at the top, we write star Calibackets and write zero. C, it will write margin zero. After that, B zero, and we get padding zero and box sizing to border box. These are the tricks which I learned working in multiple projects. But I wish I have the tricks at the beginning, and that's why I'm giving you these tricks early. Now, after that, we add styles for body and let's change our background color to has 101010. And color to FFF, which is white. Save this file. Now let's add CSS for our layout. So in our app dot CSS file, we remove all styles and app and inside this cul brackets, we write display to grid grid template rows to 80 pixel and auto. So first section height is 80%, and second section height is on auto. You already know that right, and that's all we need for layout. Save this file and take a look. We don't get our great styles. Can you tell me what is the reason? Right? We didn't import app dot CSS file in our app component, and that's what many developers forgot to do. So we write Import period slash app dot css, save the changes, and take a look. See, we get our styles. Now in the next lesson, we will create our Navbar section. 56. Adding Custom Fonts: Now, let's add font for this application. So as I told you, we have two ways to add font in our react application. In first project, we seen how to add font using CDN Link. Now let's see how to add offline font. So again, we are going to use MonstFont because that is my favorite font. So in our browser, open a new tab, and we search Monsaet Google fonts and open this first Link. Now here at the top, we have Download family option. Click on that and see Download started. Let's open this in Download folder and simply unzip it from here. Now let's open MonsttFolder. And here we have this type of folder structure. In this static folder, we have all weights of font individually. Now back to this folder, and here we have the two complete font file which contains all font weight. Here, we don't want italic, we want regular font. But the size of this font is pretty large. We can see it is 218 KV, which is the large size for font files. You can convert this font file into small size of font file. So in the browser in New Tab, we search TTF, which is our current file format to W FF two, which is the most popular font file for web browsers. Open this Cloud Convert website, and here we have to select our font. Select Monster At font, open that and click C Convert. It will take little time. And click on Download. Now in our Download folder, we can see file size is reduced to 82.8 KB, which is almost 60 to 70% reduced. Here, we rename this file to Monsratt WFF. Now, let's check this phone format is working for all browsers or not. So head over to caniuse.com, and at the top, we search WFF two. And see, it's working in almost all browsers. More specific, 97% browser support this font. So back to VS code, and in our assets folder, we create a new folder called fonts, and in that folder, we simply drag drop this font. Now, let's see how we can apply this font in our application. Open up index dot css file. Here at the top, we define our font. So just write at the font phase, and select this auto suggestion. Now here we have two properties. First one is font family, and here we pass our font name, which we want to use. So we can write here imported font or anything. For simplicity, I just write Montserrat. In the URL, we have to pass path of our font file. So in double codes, we write period slash, we have assets. In that, we have fonts, and here we have our font. Now, in our body, we add font family to Monseret Sanserif. Remember, whatever name we pass in this font family, the same name we have to pass here. Otherwise, it will not work. Save the genes and take a look. See, we have answer at font. So this is how we add offline fonts in our application. But in my humble opinion, if possible, try to use CDN link for adding fonts. I just show you this because some clients want to add their own font for their project. And this is how you can add these fonts. 57. Building Navbar Component: So let's create our Navbar section. Now, this type of N bar is very common in many applications, and also we don't want to make our app component complicated. So we can define our Nabar in the separate component. So in our source folder, we create a new folder called components, and inside these, we create one more folder called Nabar. Inside this NaBr folder, we create navbar JSX file. Also we create Navbar dot css file. Now let's create boilerplate in our Nabar component and at the top, we import period Navbar dot css file and save this file. Now back to F component, we got this Nab tag and at the place of that, we add our NaBr component and see how to import works. Save this file now back to our component at the place of this DU, we paste our NAO tag. Now, let's add all elements for our Navar. So first of all, we add one H one tag, and we write here our application name, which is movie Maniac. Now for adding three links, we create one Du and give it a class name, NaBr, underscore links. Let me show you shortcut to create this. Write dot and here we add our class name NaBr underscore inks and head tab. See, we get DV with that class name. This is called T which helps us to write code first. Now inside these Nebar links, we create one anchor tag, and we write popular here. Now, after that, we want to add Imoge for that. So in our resources folder, which you downloaded previously. And in that, we have project to folder, and inside it, we have Assets folder. Now drag all these images into our assets folder. Good. Now in our Number component at the top, we import fire from here we go two folder up sets and fire dot png. Now let's import two more images for top rated and upcoming links. Duplicate this link two more times and first we change this fire to star and image to glowing star dot PNG for last, import party from party phase dot PNG. Now for adding these images, we add image tag and we pass here, fire, and in Alt fire Imoge and also class name to NabarUnderscore Imoge. Now let's duplicate this anchor tag two more times and we change the link name to top rated and image to star and lt to star Imoge last link to upcoming and image to party and lt to party phase image. Save the changes, and we get here error. We can see it's a path is not available. So here in our parting phase, we have to correct the spelling. Save the changes and take see, we get our elements. Now, let's add styles for them. So first of all, we separate this application name and these links. So in navbar dot css file, we write Navbar, and in curly brackets, we add display two flags. Line items to center, justify content to space between padding to zero for top bottom and 30 pixel for left and right. And boto bottom to one pixel, solid has E six, E six, E six. Save this and see they are separated. Now after this NaBr, we had Nab angle bracket, H one, and in the gully brackets, one size to 30 pixel and color two has FFE 400. Now, after that, we add styles for our nga tags. So dot NaBr underscore links, angle, V target, A, and inside the culi brackets, at display to flags, align items to center, font size to 20 pixel font weight to 500, color to white, text decoration to none, and padding to zero and 15 pixel. Say these Nice. This looks good. Now, let's make this Imoge small. So we add here dot NabarUnderscore, Imo g, and into Coli brackets, we add width to 25 pixel, height to 25 pixel, and margin left to seven pixel. Save the changes and take a look. It looks nice, but we don't get our links in row. So let's inspect this and see here we forget to add display flags for Nevar links due. In our CSS file, here we add dot NBR Underscore Links, and in Guli brackets, we write display to flags and align items to center. Save the changes, and take a look. See now our Nabar looks perfect. I know I'm going a little faster for SDML and CSS part because you already know that. 58. Building MovieList Component: Now, let's build our movie list component. So we create new folder in components folder called Movie List. And inside this folder, we create a new file called movilest dot CSS, and also movilest dot JSX. Now let's add our boilerplate code by RAFC and at the top, we import period slash Movist dot css file. So we don't worry about that. Now, at the place of this DU, we add section and we add class name, movie underscore list. Now in this section, we have two parts. One is for our header line, which contain heading of the last filter and sorting and second part is movie car list. We add one header tag and give it a class name, movie list header. Now, inside this, first we add to tag and add class name, movie list heading. Now, inside this, we add our title, which is popular. And after that, we want to add Imoge. So we add image tag, and in source, we pass fire Alt to fire Imoge and pass class name to Navar underscore Imog which we added in our Navbar component. Now we have to import this fire Imoge at the top. Import fire from here we go two folders up assets and here we get fire dot png. Let's add D for our filter and shorting and give it a class name. MovistFsFs for filter and shorting. Now, first, I want to add one unordered, and inside this, we will add filtering item. So we write al dot MV underscore filter, angle bracket, dot, movie underscore filter, underscore item, multiply by three, and press tab. See, here we get this code. This is the power of Emet. Now we pass here eight plus star, seven plus star, and six plus star. Now, after this list, we have to add two drop down boxes. So we add select dot MV underscore shorting. And inside this, we want three option. Now for first option, we pass sort by, which is default, dating, and rating. Now we can simply duplicate this select tag, and here we only want two options. So we can remove this one option, and here we write ascending, and at last, we have descending. Save the changes, and we get nothing because we forgot to add movie list component in our app component. So in app component at the place of this main content, we add movie list component. Save the changes and take a look. See, here we get our elements. Now, let's add styles for them. So in move ilst dot CSS file, we add dot movie underscore list. And in the curly brackets, we add padding to ten pixel for top bottom and 30 pixel for left right. After that, we set display to flags, Alan items to center, justify content to space between because we want to separate heading with filter and sorting. After that, we add margin bottom to five pixel. Now we add styles for our heading, so dot Movist heading. And in the clipackets we add display two flags, line items to center and font size 226 pixel. Color two has FFE 400 sayings and we don't get our styles here. So let's check this. In our movie list component, here we can see we have to add style for movie list header. In our CSS file, we change this movie list class to movie list header class. Say the changes and see, we separate these two parts. Now, here I know font size a little small. You can increase them by your needs. Now, let's set styles for this filter and drop down. So back to VS code, and we add here movie is FS. And in the Cali brackets, we add display to flag line items to center. Now here is one thing. We are repeating these two lines many times in our application. See here, here, and also we used in Nabar CSS file. So let's create separate class for these two lines. So cut these two lines and open index dot CSS file. At the end, we add new class, Align underscore center, and inside it, we will paste our styles. Now, whenever we want to add these two styles, we can simply add this Align Center class to that element, and that's how Telvin CS is made. Save this file, and in movie list dot CSS file, we have to add Align Center class for these two elements. So we remove these two lines from here. And also remove this class style. Save this. And in the movie list component, first, we add Align Center before header, and also add Align Center before this heading. Also, for this day and also before this movie underscore filter. Save the changes, and this is working fine. Now, back to movie list dot CSS file, we add dot movie, filter, list style to nan, one size to 16 pixel. Now we add dot movie, filter item. And in the calibracedes, we add padding to five pixel and ten pixel and cursor to pointer. Now after that, we add style for our drop down. So dot movie shorting and inside these cul brackets, we add border to nun, outline to Alsan Border radius to five pixel font size to 16 pixel font weight to 500, font family to inherit, so it can use MonsetFont inside our dropdown. After that, height to 30 pixel, adding to zero and five pixel and margin to zero and ten pixel. Save the changes and take a look. See, we get our styles. Now, at last, I just want to display this selected filter so user can see what filter they have selected. So in mobilised component, in this list item, we add one more class called active. We will switch this active class for active filter. Save this file, and in the CSS file, after this movie filter IAM, we add move filter m dot Active curly brackets and inside this Boer bottom to one pixel solid has E six, E six, E six and font weight to 500. Save the changes and take a look. See, this looks beautiful. Now, after this header tag, we create one more du with class name, movie underscore cards. In this du, we will add all our movie cards. So in the next lesson, we will create this movie card component. 59. Building MovieCard Component: Now, let's build our last component which is movie card component. So in the movie list folder, we create a new file called movecard dot CSS, and we create another file called movicardt JSX. The reason we create this component in movilistFolder, because movie card is a part of movieist component. You can also create separate folder for that. It's totally up to you. Now let's add boilerplate code, and at the top, we simply import period slash movecard dot CSS file. Nice. Now in this component, we return anchor tag because when someone click on movie card, then we will open that link, and we give it class name to movie underscore card. Now in this anchor tag, we want to add our movie poster. So add Image tag and add class name to movie underscore poster. Now let's find some dummy poster for temporary. So in our browser, open a new tab and search movie poster image, and select any of them image and right link on the image and copy image address. Now back to VS code and paste this link in the source, and in Alt we add movie poster. Save the changes, and we again get nothing because we again forgot to add this movie card component in our movie list component. So in move List component, we add here movie card component. Save changes, and C, we get our post. Now, in our application, when we hover our mouse on movie card, we want to display some details about movie like name, release date, rating, and little description. So after this poster, we will add one DU with class name, movie underscore details. After that, we add S three tag per movie name and add class name to move underscore details, underscore heading. And inside these, we write movie name. Now, after that, we add one day with class name, movie underscore date, underscore rate. And inside this, first we add one paragraph in which we show movie release date, and after that, another paragraph for displaying rating. Now at the right side of this rating, we want to display the star icon. So we add image tag, source to star, Alt to rating icon and give it a class name to card underscore Imoge. Now we have to import this star icon. At the top, we import star from. Here we go to folders up assets slash star dot png. Good. Now at the end, we want to display a little description. After this dU we add another paragraph tag and give it a class name to movie under Scot description. Inside this, we add Dummi text, BLR 15 and press tab. The ging es and take a look. See, we get our ugly elements. So in the next lesson, we will make them beautiful. 60. Styling the MovieCard Component: So let's quickly add styles for movie card component. First of all, I close all other files. Now in the movie card dot CSS file, dot movie Card. And in curly brackets, we add width to 200 pixel, height to 300 pixel, margin to 15 pixel, overflow to hidden water radius to ten pixel, color to white. And box shadow to zero pixel, three pixel, eight pixel for blur, RGBA, zero, zero, zero, 0.25. Now, after that, we add dot movie poster and inside it with 200% and height 200%. Say the changes and see, we don't get our styles. Let's find out the issue. So right click on our card and go to inspect. Select this anchor tag and see here our width and height are not applied. And it is suggesting us to try setting display to something other than in line because if our element is set to in line, then that will prevent width property. But there is another way to solve this. We can make our movie cards due to flags. So in move list dot CSS file, we add dot movie cards. And inside this, we write display to flags. Flex wrap to wrap and justify content to space evenly. Set the changes and see, we get our card here. Now we have to show our movie details section. So here we need to use position absolute. So first of all, in movie card CSS file, we make our movie card element, which is our parent element of these movie details and set its position to relative. And after that, at the bottom, we add dot movie details, and inside these, we add position to absolute top to zero. Width 100%, height to 100% and padding ten pixel. Say this, and here we get this movie details. Now, let's tile this text. So back to our CSS file and we add here dot movie Details adding and inside this one size to 16 pixel and color two has FFE 400. After that, we add dot movie, date, rate, and inside the scur brackets, display to flag, align items to center. Oh, sorry, we already created class for this. So we remove these two styles, and we add justify content to space between font size to 12 pixel font weight to 500 margin to five pixel for top bottom and zero for left right and color has FF E 400. Now, let's in movie card component first add Align Center class before this class, else, we will forget it. Save this file and back to our CSS file. Now, after that, we had dot card Imog and inside this, we set width to 20 pixel, height to 20 pixel, and margin left to five pixel. And at last, we at ME Underscore description, and in it font size to 12 Excel and font style to Italy. Say the changes and take a look. See, here we get our styles, but we need to make some changes. First, we want to add little background for this details se so a text looks clear and also we want to place it at the bottom. So back to Vacde and here in the movie details class, add background image to linear gradient, and inside it, we pass two colors for gradient. So RGBA, 00, zero, zero, RGBA, 00, zero, one. These both are black color, but first one with zero opacity and second one with one opacity. After that, we had display to flags, flag direction to column and justify content to end. Schans and take a al. See now our details looks very clear, and that's the power of gradient. Now here, I don't get any effect for this date and rate line. So let's see what we did wrong. Back to our movie card component. Here we can see we have class name, movie underscore, date, underscore rate. Probably I make mistake in this spelling. Let's inspect our card and see the DU and see. Here we are not getting styles for that. So back to our CSS file, and I correct our class name, see the changes and take a look. See, we get our details properly. Now we want to show these details only when we hover this card, and we want to also make it big when we hover. So at the top, we add that movie card call Hover Effect and inside this, we simply add transform to scale 1.08. Now in the movie detail styles, add one more property, opacity to zero by default. And when we hoo our movie card, then we will set its opacity to one. So dot movie card, call and hoover dot MVE Details. And inside this opacity to one. Simple as that. Say gangs and take a look. See, here we get what we want. Now this effect is very sudden. We want to make this smooth. So in our movie card styles, we had transition to all 0.2 second is in out. And also, same we apply to movie details. Say the changes and take a look. See, here we get smooth effect. So here we have all components ready with styles. Now we just need to add functionality to our project. If you are continuously watching this course, then take ten to 15 minutes break and get some fresh air. Take care of your eyes, and I will see you in the next lesson. 61. What is an API: Before we start calling an API, let's understand what is EPI. API stands for application programming interface, and it is a way for two programs communicate with each other. Let's understand this with the example. Here is a restaurant. We are sitting on the table one and we want to order some food. In this case, what we will do? We do not directly go to the kitchen and order our food to chef. Instead of that, we will call a waiter. Waiter will take our order and then give it to the kitchen. After that, kitchen start making process of our order and give food to the waiter. And then waiter will deliver the food to our table. So here, waiter is like messenger who takes our request and pass the request to our destination. And then it will get reply message from the destination and bring it back to us. So imagine this table one on which we are sitting is our application front end. We want to get some data about clothes, so we will call API, which is our waiter and send requests to eat. Now, API will transfer that request to server or database, which is our kitchen, and that server or database will share the response, which is the data we want, and API deliver the response data to our front end. So now you understand what is API, EPI is a way for two programs communicate with each other. Let me explain you with another real world example. So you probably visit the website which books the flight tickets, right. So in that application, let's say Emirates we write our departure city. Let's say London and place to reach, let's say Mumbai. And we enter our dates type of seat, and we search the flights, and it will display details for flights. That's possible because of API. We call an API, and that API will get this data from server and give us that data. Simple as that. Here is one thing. As we are using this emirate site, we are only getting the flight details of emirate flights. But there are some websites on which you search flight details and they will return multiple flights with multiple airline companies. How is that possible? Many company launch their API to public usage, and we call that API as public API. By using this public API, we can access their data. Now as the data is open publicly, company has to use some protection. And for protection, many public API has its API key. So when our front end send requests to API, front end needs to send APIkey with that request. After that, API will pass that request to server, and before taking the request, server ask for APIKe to access the data. So our API pass our APIkey to the server, server verify that key if it is authentic, only then server will return data. Otherwise, server returns error, access denied. Simple as that. Now you might ask, how can we get APIKey if we want to access public API? For getting the API key, we have to register on their website, which companies providing the API, and they will send us APIKey. In the next lesson, we will get our APIKey for movies data. 62. Generating the API key: So in our movie maniac project, we are going to use public API of TMDB for getting the data of movies. We are not creating the API here. We are just using the public API. The reason I want to teach you public API is nowadays, it is very common feature of application. For example, some application, so the weather information and what they are using just public API of another company. By using public API, you can make your application more useful. And also, if you are applying for React developer job, then by looking at your project, interviewer also know that you can also use public APIs. So let's see how we can get TMDB API key. So head over to TMDB website and go to more Option and open API option. Here we can see this API link option to register for APIKey. Open that, and here you can see a TMW user account is required to request an APIKey. So let's get our APIKey. So click on join TMW Link and fill this form with your details. Username Cb 24, Enter your password. Again, write confirm password and enter your rea Email account and click on signup. Now we have to verify our email account. So open up your email and open TMW email and click on Activate My Account. Now we can close this. Now we can login into our account. So write your password here and click on Login. See, we redirect to our dashboard. Now here we can see we have to request for the API key. So click here and select developer. And accept this agreement. You can read that if you want. Now we have to fill this last form for APIKe. I know this is little long process, but they are giving us useful data, and this process is very common for getting APIKe of any company like Google or Facebook. First of all, select type of use, personal application name to movie Maniac, application URL to local host Column 5173 application summary to movie Miniac is application which so popular, top rated and upcoming movie details. Now after that, write your first name, last name, phone number, address one, address two, city, state, post code, and at the end, click on submit, and we have to write wrong address. Now, click on submit and see here we successfully get our API key. Now let's see how can we get API. So open this documentation link and here we have to go API reference section. And in this documentation, they explain each and every endpoints of their API. But we only want to get movie API. So scroll down this section and go to movie detailed section. Now here we get this popular top rated and upcoming API. So let's open popular now at the right side, we can see the details about that API. Note that here our SDTP method is GT. We will discuss these SDTP methods in upcoming sections in which we will see how can we call our private API. For now, just remember, GET method is used to getting the data from API, simple as that. Now don't worry now just copy this API from here and in our new tab, we open that API. See here it returns error called invalid API key, and you must be granted a valid key. Basically, it is asking for API key. Back to our M API settings tab, here we can see we have this API sample, so we just copy this question mark and API key variable. Now in our TRL, we past that APIkey as Squery string. And see here we are getting the popular movies data. If you wonder how you can see your data in this beautiful format, then you have to install one Chrome extension called JSON Viewer Pro. So congratulations. You create your first API key. 63. Calling API using Fetch method: Now, let's see how can we call this API in our application using Fetch method. Trust me, it is really simple and easy. Now, before we call API, we need to decide in which component we need to call API. So we need movies data in our movie list component, and using that data, we'll display it in movie cards. Now here we want to call API when this component gets surrender. Do you remember which hook we will use for running logic on component render? Right, we will use use effect hook. Now, as I told you, use effect is used for three different variations. Here we need second variety, which is passing empty array at dependency array because we want to only call API one time when this movie list component gets surrender. So we will write here use effect and press tab. C, it is automatically imported at the top. Now in effect, we know we have to pass two arguments. First one is for callback function, which is the function we want to run, and second is dependency array. Here we pass empty array. Simple. Now in this callback function, we will write our logic to call API. So for calling API, we are using fetch method. If you already worked in JavaScript, then you already know this concept. And if you don't know fetch method, don't worry, see this and you will understand it. So here we add fetch method. Now in this function at the first position, we have to write our API URL. Back to browser, and here we copy our API URL. And in our patch method, in double codes, we will paste it. Now, this expression returns a promise. Basically, promise means we will get the result in the future, not immediately. Result can be our data, or if something went wrong, we will get error, but we definitely get anything. Let me show you what I mean. So we will store this in variable called response. And after that, simply console dot log this response. Save the genes and take a look. Open up Console and see here we get promise. If we expand this promise, here we get promise state to fulfilled because this API is working. And in this promise result, we get a response from API. And in this response body, we will get our data and other details about API call. For handling the JavaScript promises, we have two methods, then method and acing await. Don't worry. We will see both one by one. So first of all, let's remove this response variable and also console dot log. And after this fetch method, we add dot DN. Now in this ten method, we have to pass callback function. And here we get our response as parameter arrow function. And now let's simply console dot log this response. Save this and take a look. See, here we get a bunch of properties related to our API call, like status, URL, body. This body has all our data. Now you might think, why can't we see that? It's because we have to convert that data into JSN format. So at the place of this response, we write response dot JSON. Save this and see we again get promise here. And in this promise result, we get our movies data. For accessing this data, we have to return response dot json from this function. And because of that, we get another promise. Now, we again use then method for handling that promise. And inside this, we write callback function and we get here data as parameter, and we simply consult dot log this data. Save this and take a look. See, we get movie data in these results, so it's working. Now this patch method with two than methods looks a little bit ugly. Let's see the second method of handling promise. Let's remove these two than methods. We don't need them. Now before this patch method, we add a wait, which means our code will wait for this promise to complete execution. You don't know these concepts, then I highly recommend to watch Fetch Method and Async Rona Java Script tutorials. These are really very important concepts. Now to use await, we have to make our function async. So here, after our use effect, we will create a new function called Fetch movies. Now to make this function asynchronous, we have to pass an keyword before this parenthesis. Now let's move our fetch method into this function. Good. Now we know that this expression returns response. So let's store that in variable called response. And after that, we simply consult or log that response. Now, don't forget to call our patch movies function in our use effect. Save the genes and take a look. Refresh the page and see we get the same response which we get in our first then method. So we have to convert that response into JSON format. So we write here response dot JSON. And this will return again, promise. So we will again write here await, and let's store that JSN data in variable called data. And at the end, let's console dot log this data. Save the genes and take a look. See here we get our data. And by using acing await, our code looks clean. So whenever we want to display data from API call, we will follow this method. If you have little confusion, then don't worry with practice, your confusion will go away. And I added one whole section, especially for calling API. So don't worry about that. 64. Exercise for MovieCard: Now it's time for little exercise. So in the previous lesson, we get our movies data. Now, you have to display the data in multiple cards. Here are some properties you have to use. Hint is, you have to use UTT Hook for some reason. So spend some time and try to solve this exercise. And after that, come and watch the solution. 65. Solution for this exercise: So let's see the solution of this exercise. I hope you try to solve that. So first of all, at the top, we will create one state variable for storing this movie data. So write use state and press tab, I will import use at the top. And now write use state Snippets, movies, and set movies. And as the default value, we pass empty array. Now at the place of this console dot log, we simply use set movies and store here data dot results because we are getting movies array in data dot result. Now, let's display these movies in our movie card component. So here we at culibackets, movies dot MAP. And inside this, we get single movie item, arrow function, and we return movie card component. Now do you remember whenever we use map method, we have to pass uni value as key. We add key and pass here move dot ID, which is unique for every movie. Now, here we have to pass each movie details, which we want to display in our movie card component. At the place of passing each details individually, we can pass whole object in one variable. Let me show you what I mean. We simply pass here, movie equals to, and we pass here each movie item. Save this file and open movie card component. And here we can destructure our movie props. Now, first of all, let's display all text. So at the place of this movie name, we write move dot original underscore title. At the place of this date, movie release underscore date. Rating to move dot rate, underscore average. And movie description to move dot overview. Save this and see here we get our details. But this movie description is very long. So let's first solve this. If you solve this exercise to this point, trust me, you are doing really great. So there are many ways to do that. We simply add here dot slice method and pass zero and 100 and after that, plus in double codes dot dot dot. So basically the slice function will only display the first hundred letters, and after that, we display three dots. Save these and see we get this nice description. Now, let's change our poster. So go to the setting tab and open documentation of TMDB API and here in the images section, we open this basic step. Here they mention how we can add images path. So simply copy this image URL, and at the place of our hard coded image, we add Cully brackets, backticks and simply paste here that URL. Now in this URL, we only need to change this image ID. So we remove this image ID and also remove one slash and simply add dollar Cali brackets, move dot Poster Underscore PAT. The reason we remove that slash because slash is already available in poster underscore path variable. Save the changes and take a look. See, here we get our movie posters. We want to open official page of that movie on TMW website when we click on Movie card. So here in our anchor tag in HRF, we add again curly brackets, backticks, and here we pass HTTP as Colmlaww the movie db.org slash MOVlaTlar c Brackets, move dot ID. We want to open this link in New Tab. We add here, target equals to underscore blank. Save the changes and take a look. Click on any of the card and see it will open in New Tab. Perfect. Here, we completed our basic part of this application. I hope it is fun and learning experience for you. If you have questions, you can ask in Q&A section. Now in the next section, we will start implementing filter and shorting features. 66. Section 07 - Filtering, Sorting & Dark Mode Features: Welcome to the Section s of the Ultimate React course. In this section, we are going to see how we can implement the filtering, sorting and one bonus functionality, which will make our application stand out from a crowd, which is dark and light mode feature. I'm very excited about this and hope you are too. So let's start this. 67. Filter vs Sort: Before we start implementing filter and short functionality, let me clarify the basic difference between the filter and short features. So we use filter functionality to filter out some data. For example, in our application, if we click on eight plus star rating, then only those records should display whose rating is higher than eight star. So we are filtering other movie data. Now, at the other hand, shorting is for arranging data. Example, in our application, if we select shot by date, then we have to rearrange our movies data so that functionality is always arranging data in the order. It will not remove any data, and that's what we call shorting. So in simple words, filtering is we are keeping only useful data, and shorting is we are keeping data in some order. The reason why I explain you this is this explanation will help you to clearly understand and implement logic. 68. Implementing Filter Feature: So before we start writing logic for filter, first, we need to get the current selected filter. So after this movie state, we create one more use state and give it a name, mean rating, and set mean rating. And as the default value, we pass zero. Now what we want to do is when we click on this list item, then we will set our mean rating to that rate. It is really simple. Let me show you. So click here, and if you have Windows, then hold Alt or if you have Mac, then hold Option. And now click here and here. By using these, we can create multiple cursor, and we add here on click event, arrow function, handle filter function. Press SCA for removing multi cursor and simply pass here rating eight, seven, and six. Now let's define this function. We can minimize other function like this. This technique I always use when I writing more lines of code. Now, after this function, const handle filter, and here we get rate, arrow function, and inside this first we set Min rating to this rate. Now, do you remember what method we will use for filtering data? Right, it is filter method. You already know that. Nice. So we simply write movies dot Filter. And inside this, we get each movie error function, and here we have to pass condition. Move dot vote underscore average greater or equals to rate. Simple as that. Now, this filter method will return a new array. So we store that in variable called filter. And now we can set movies and pass here filtered movie. Save the changes and take a look. Now before we check our functionality, I notice in this movie details, we don't get rating. So let's fix this. Open movie card component and scroll down to movie details. Here we have to change this rate average to vote average. Save the changes and see, here we get our rating. Now, click on Filter. Let's say seven and see it's working. Now, click on eight, and it is also working. But here is a one major bug. Again, click on seven or six. It will not work. Let me explain to you what is happening here. So when we select rating seven plus, this handle filter function will run. Inside this, our mean rate state will update with seven. After that, this filter method will filter movies and we set that movies in this set movie function. Now if you click on rating six plus, then this filter method will filter only previously filtered data, which all are seven plus rating instead of using our original 20 movies, and that's the issue. Let's solve this. Solution is we will originally set all movies in this movie state variable from API and after that, we will not touch that array. Will create one more state variable and store our movies in that variable. And when we want to filter our data, we will get data from our original movie state and then store our filter data in our new state variable. I know this is a little confusing, but just see this and you will understand it. So here we create one more state variable and give it a name filter movies and set filter movies. And as a default value, we will pass empty array. First of all, we have to fill these filter movies array when we call our API. So we duplicate the set movies line and we pass here set filter movies. So these filter movies and movies are both equal. Now, in the Handel filter function at the place of the set movies, we had set filter movies. So we are not messing with the original movies array. Instead, we are just using it for storing original data. Now at the bottom, we have to use filter movies at the place of movies array. Say the changes and take a look. Select seven, then eight, then six, and C. Now it's working properly. Now, if we selected filter six, then if we again click on that filter, we want to display all our movies. Let's implement this. Here in the handle filter function, add if condition rate equals to mean rating. And inside this, first, we will set mean rating to default, which is zero, and after that, set filter movies to our original movies. And else we will run over this logic. Simple as that. Save the changes and take a look. Click on rating eight, and again, click on rating eight. See, we get data back. So it's working now. Now, here is a one last change. We want to display the current selected filter. So back to VS code, and at the place of this string class, we add Ci brackets, and here we add condition I mean rating equals to eight. If it is true, then we will return to classes, movie filter item and active else we return only movie filter item. Let's copy this expression and paste it for these both filters. And just change here seven and six. Say the changes and take a look. See, here we get this active filter line. You can see how simple it is to implementing filter feature. Now, here in our movies filter, this is repeatable process. So we can separate our filter movie component and that we will do in the next lesson. 69. Creating Resuable Filter Section: So instead of just putting this list item in separate component, we will put this whole unorder list in the new component. Let's cut this and in our movie list folder, we create new component called filter group dot JSX. Now here we add our boilerplate and simply return our under list. Now in this component, we need these two properties, Min writing and handle filter function. So how can we get that? Right? By using props, you can see react is very simple. Save this file and back to our movie list component. And here we add filter group component. Now inside this, we pass Man rating, equals to mean rating. And for handle filter, we pass props on rating clique equals to handle filter. You can see here we are using these related names because that is the best practice for developer, and we can better work with other developers also. Save this. And now in the filter group component, at the probs, we destructure it and get here mean rating and on rating click. Now, let's replace this handle filter function, press Control plus D or Command plus D to select the exact same code, and just write here on rating, click. Save the changes and take a look. See it is still working. Now, one more thing I want to change in this filter group component. So today, we want to only show three filters. Tomorrow, if we decide we want to add five plus four plus or nine plus stars, then we have to multiple times duplicate this list item, and that is the bad practice. So we can use array for that. So a movie list component and we add here one more props called ratings equals to in Cali brackets, we add array, and inside these, we add eight, seven, and six. So if you want to add or remove one filter value, then we can simply do that by using this rating array. Save this file and back to filter group component at the top we get ratings. Now, after our noun list, we add Calibrackets, ratings dot MAP. We get here single rate error function, and we return this list item tag. Now, at the place of this hard coded eight, we add rate here, also rate and here also Ci brackets rate. Now, here we are missing one thing in map method. Can you tell me? Right. It is key property. So we pass key equals to O rate. Here, our all rates are unique, and that's why we can pass it as key. Otherwise, we will add index. Now, let's remove these two list items. We don't need them, save these and see how clean our code looks using this array method. 70. Handling Sorting Selection: Let's see how to handle sorting selection. So first of all, here we have to create one state variable for storing sorting details. So state give it a name shot and set sort. Now as a default value, we pass here object. This object has two properties. First one is buy and we set it to default and order to ASC, which means ascending. In this first buy property, we can add shot by date or shot by rating. And in order, we store ascending and descending. In our first select tag, we pass name to buy, first value to default. Second value to release underscore date and third value to vote average. Now in the second select tag, we pass name to order, first value to ASC and second value to DSC, which is descending. Now you might think why we pass only these values. Don't worry about that. I will explain you later. For now, we just focus on handling this selection. Do you remember how we handle multiple inputs using same function? Let's apply that trick here. We pass here one event, one change equals to handle short. And value to shot dot buy. And also for this select, we pass the same change event to handle Short. And value to short dot order. Now let's quickly define this handle short function. After this handle filter function, we define new function called handle short equals to here we get event object, arrow function. In this function, first, we will get the name and value of current input. So C object, name value equals to E target. And after that, we call set sort. First, we get previous value, arrow function. And here we simply return object. And in that we add previous values using spread operator, and after that, in square bracket, name Callan value, simple as that. Now we can even make this code shorter. So I from function, we want to return object, then we can remove this return and also remove the C bracket and wrap our object in parenthesis because if we direct at curly brackets, then our code understand that ci brackets is code block. Now, let's see we get our value in this short variable or not. So we simply consult dot log this short, save the changes and take a look. Open up Console and select date from this drop down and see it is set to release date. After that, we select descending, and here we also get that. Now, here is a one little issue. Whenever we want to see any of our components state, then we have to consult or log that state variable, which is little boring. In the next lesson, we will use debugging tool for react application. 71. Debugging React Application: So for debugging the react application, we will use the most popular browser extension called React Developer Tools. So open a new tab in your browser and search Chrome Web Store. Open the first link. And in this search box, we write React Developer Tools. If you are using another browser, you can directly search on Google React Developer Tools extension for that browser. You can see this extension download by 4 million users, so it is pretty popular. Now click on AttucRom and give it a permission to add. Good. It is added. Now close this tab. We don't need it. Let's open Developer Tools. And in this list, here you can see option called components. Open that. So this is our application component tree. You can see here we get our app component, which is our root component. After that, we have Nabar and after that, movie list, and in the movie list, we have filter group and bunch of movie card component. Now here we can see all components state by selecting them. So we select movie list component. Here we can see hook section, and this is our short state. If we change our short value, see, we can see here that value. And here we can also see movie list. Now, if we want to see the code snipit of this component, then click on this code icon and see here we get our code. Now back to components Stab. Now if we have complex t structure, then we can also search our component in this search box. So overall, react developer tools is very useful tool for debugging and understanding react applications. We can view the componentry, state, props, and much more. And by using these, we can easily identify and fix issue in our application. 72. Implementing Sorting Feature: Now, let's implement sorting feature in our application. So there are many different ways to implement shorting feature. So here we are going to use one external library called LDsh. It is very popular library in JavaScript for handling objects and array. So open up terminal, and in the new terminal, we write NPM I dash. Zi short for Install. And if you want to use the exact same version, which I am using, you can write aerate 4.17 0.21 and height Enter. See it installed. Let's minimize this terminal good. Now to use any library, we have to import that library from its package. So at the top, we write import underscore from Low dash. Here, you can also write Low dash or any other name, but this is the most common name which developers like to use. Now you might think, why I write imports sometimes here and sometimes below this list. So whenever I want to import anything from the packages, then I import them at the very top. And if I want to import anything from local components, images, physically, what we create in source folder, I import that in this second list. By doing this, we can easily see what packages we are using and which components we are using. You can also separate it or you can write all inputs together. It's totally up to you. But whatever you do, do the same in all components. Now let's focus on sorting feature. And one thing I want to tell you about react is react runs state update in synchronous way, which means if we change our short state in this function, then react will not update that state immediately. Let me show you what I mean. So here we set short to current selected sorting methods. Let's simply move this console dot log here. Say the changes and take a look. Change something in the drop down and see, here we get our old shot straight. If we again change this shot to rate, C, we get previous state. So that's clear, react is not updating the state immediately. But why react works like this? Let me explain to you. So when in react, one functions run, react first, let the whole function run. And if there are multiple state updates, it will stack them in a row and then run it one by one. After completing this full function execution, because if react immediately update a state, then that bring unwanted re render for that complete component, and that is not a good thing. That's why react runs state change commands after completing the full function execution. So we can write our sorting logic in this handle sort function. We need to use something which automatically runs when our short state will change. Do you know about something similar, which we already used? Right? It is use effect hook. After this use effect hook, we add another use effect hook. And as we know, first argument is our callback function and second argument is dependencies array, and in this array, we pass our short state. Now inside this callback, we add one condition I short B not equals to default. We don't want to short anything for default state. Inside this, we write underscore, which is our low dash dot order. This method is used for shorting and change order to ascending or descending both in same function. So at the first position, we have to pass our current array which we want to short, which is filter movies because it can possible that we filter movies only seven star plus, and then we want to short that. Now at the second parameter, we have to pass array and inside this, we have to pass the property by which we want to short. So SOT dot B. And inside these, we can also pass multiple properties. Now at the third parameter, we have to pass, again, array, and inside this, we have to pass ASC for ascending or DSC for descending, and we store that value in sort dot order. Just remember at first parameter, we pass our array which we want to shot. At the second parameter, we pass array of properties by which we are going to shot. In our case, it can be release date or vote average which are available in movies array. And last at the third parameter, we pass ascending or descending, simple as that. Now, this expression returns a new array. So we store that in variable called shorted movies. And after that, we set filter movies two sorted movies. Simple as that. Also, from our function, we remove this console dot log. We don't want it. Save the changes and take a look. Close our console, refresh the page. Set our sorting to date and see it is changing. Now change order to descending and see it is also working. So you can see how simple it is to implement sorting using this loads package. If you don't want to use that library, you can write shorting logic by yourself like this. It's totally fine. But in my humble opinion, this loads library works best for us. I personally used it in many clients projects. 73. Adding Switch for Dark Light Mode: Now let's see how we can add dark and light mode switch in our project. So I create this switch for my client project using your STML and CSS. So in the resources folder, open our project two folder, and here we get this dark mode component folder. So simply drag this folder into our components folder. And that's it. This is how you can use other project components in your project. That's the power of creating separate components. Now, let's see what is inside this component. So dark mode component, and here we can see we have one input with type check box, and after that, we have label, and in that, I added twos which is component, sun and moon. Let me show you how this look. So press Control plus P or Command plus B and search Navar component. Now, at the top, we have to import dark mode component from dark mode folder, and we add this dark mode component before our nav links. Save the changes and take a look. Here we get some error. Let's open Console and see here we get this error. This is because white does not support this react component import, by using this, we can import SVG as component. To solve this issue, we have to use library called White plug in SVGRNpMitPlug in SVGR and it Enter. Good, minimizer terminal and open white dot config dot JsNFle. Now, here at the top, we input SVGR from white plugin, ds SVGR. And in this plugins array, after this react, we call this function. Save the changes and take a look. See how beautiful this switch looks. You can use whatever switch or design for this. It's totally up to you and you can also modify this dark mode CSS. Now, here in the dark mode folder, we can see we have two Swigs. We can place them into our AssSFolder so our project will better organized. Select these both Swiges and move them into Assets folder. And suddenly we get this error, which says SVG not found in current location because we moved it. So we have to change our SVG path. So here we go two folders up, SATs and sun dot SVG. Same we do that for this path also. Moon dot SVG. Save this and it works again. Now the reason why I give you this ready made dark mode switch because it is pure STML and CSS based. If I explain you each and every STML and CSS part, then many people get spored by that because we are here for learning react. Also, I will give you the link of Ts tutorial in which you can see how to create this switch from scratch. 74. Dark Mode Implementation: Before we start implementing dark mode functionality, first let's understand the logic of changing the theme. Basically, we are only changing colors of our website. Simple as that. We are not adding any elements or changing the size of elements. Nothing. We are changing the colors of our application. So the best solution for this feature is we define CSS variables for every color in our website for dark theme by default. And when users change the theme to light, we replace those all variables color value, simple as so in this dark mode component, first we create one function called set dark theme. And in this function, I want to add one attribute to body element. So document dot query selector and pass here body. Dot set attribute, and here we pass attribute name, which is data theme comma, and we set to dark. So by using this property, we will get our theme state. Now let's duplicate this function and change this function name to set light theme and attribute value to light. Now let's call one of these function here. Let's say set dark theme and see if it's working or not. Save the changes and take a look. Right click on the page and go to inspect. In the body tag, you can see here we get data theme to dark, so it's working. Now we want to toggle them on change of this togal so we write a new function called Tgal theme, and we get here event object, error function. And first of all, we check if event target dot check is true. Then we call set dark theme function, se we call satellite theme function. Now we want to pass this function in this input on change event. So we on change equals to togal theme. Save the changes and take a look. See, when we toggle this theme, it will change here. Now, let's change in CSS. So pan index dot CSS file. First of all, at the top, we use column root. And inside these, we declare all color variables for application dark theme because we want to set dark theme by default. So write double dash and write variable name. Let's say body underscore background, and value two has 101010. Next, we have double dash, body underscore color, and value to white. And next double dash adding underscore color and value to a FFE 400. If you are working on other project, then you have to add all colors in these variables which you want to change. Now, let's define color variables for light theme. So we have to target here data there's theme equals to light. You want to light theme as default, then you have to add light theme colors in this root, and in this condition, you have to add dark. Now, inside these, we define double dash, body underscore background, and value to white. Make sure you use the same variable name for light theme as well, so it will replace these dark theme variables. Next, we have double dash body underscore color. Value to black, and at last double dash heading underscore, color, to also black. Now we have to replace all colors in our CSS files with these variables. So here, in the body, we change this background color value to variable, and in that, we pass variable name, double dash, body underscore background. Color to variable, double dash, body underscore color. Save this file. Now, let's replace colors to variable in other CSS files. So panabar dot CSS file. Here we can change this heading color to variable, double dash, heading, underscore color. And also, we change this link color to variable, double dash, body underscore color. Save this file. And now let's check movie list dot CSS file. Here we have to change this movie list heading color to variable, double dash, heading underscore color. You might think why we are not changing this border color because we don't want to change its color when we change the theme and that's all we want to change. Say the changes and take a look. See, here we get dark theme and if it to gal we get light theme. But by default, this slider is on light mode. In the dark mode component in our checkbox input, we pass one more property called default check equals to true. Save the changes and see it is on dark mode, so it's working. But this changing theme is very sudden. Let's add little transition, so it will be smooth. So here in index that CSS file, in our all styles we add transition to all 0.3 second is in and out. Save the changes and take a look. See, we get this mode transition. Here is one thing. If we refresh this page, it will by default, start with dark theme. But we want our application to remember if you use a togal to light theme, then on refresh, it will stay on light theme. So we have to save that setting in local storage, soap and dark mode component. And in this set dark theme function, we add here local storage dot set item to selected theme and value to dark. Now copy this line and paste it in satellite theme function and change its value to light. Now, after that, we create variable called selected theme and we get here our stored theme. Local storage dot get item, and we pass here this name which is selected theme. Then we add condition if selected theme equals to light, then we call this set light theme function. Otherwise, it will by default, start with dark theme. So we add and simply call here set dark theme function. Save the changes and take a look. Set theme to light mode and see, now we refresh the page, we still in light mode. But here, we have to fix this togal button. So in our input tag, we simply add in default checked attribute, selected theme, not equals to light. So if our selected theme is empty string or dark mode, the slider will stay on dark mode. Save the changes and see now our Togal switch is working well. So you can modify this code according to your needs. But the logic of dark mode will remain the same. 75. Making MovieList component Reusable: Now currently our movie list component is static. We want to make it reusable, which means we can pass heading name, icon, and we will call different API for top related movies and upcoming movies. So let's do that. Let me show you my trig which I used to know which data we want to pass through props. So on move list component, first of all, we want to change this API. So back to TMDB API documentation. Open top rated movie API, and here we can see it is the same API URL, which we used for popular movies. Just we have to replace popular with top underscore rated. And for upcoming movies, we have to just pass upcoming. We destructure the props here and first we add type, which can be popular, top rated or upcoming. We change the double codes with back ticks and at the place of this popular, we pass dollar cul brackets, type. Now next, we want to change this title dynamically. We pass here Culibackets and pass here title. We also change this Imoge we pass here Imoge. And also we change this t with ticks, dollar, colli brackets, Imoge icon, and that's it. Let's add these properties in props. So title and Imoge. So this is very clear. We have to only pass these three properties as props. Now at the top, we can remove this image inbot. We don't want that. Save this file and back to our app component. In this movie list component, we pass here type equals to popular title to popular and ImogeTFR let's import this Imoge. At the top, import fire from period slash assets and fire dot png. Let's also import adhere to Imoges. So import star from period, assets, glowing star dot PNG. And at last, import party from period, assets parting, past PNG. Let me verify the spelling. Yes, it is right. Now let's add adhere to movie list for top rated and upcoming. So duplicate this component two more times, and for a second, change type to top underscore rated, title to top rated and Image to star. And for third type to upcoming title to upcoming and Image to party. Save the changes and take a look. See, we have three different section for movies. Now, at the top, we have Neva links which are not doing anything. So when we click on top rated Link, then our page should scroll to the top rated section. And if we click on upcoming link, then our page should scroll to the upcoming section. Implement that. It is very simple. So in our movie list component, we have already type props, so we can pass the type as the ID of this movie list section. And that's the power of creating reusable components. You can see in compared to SDML, CSS and JavaScript application, we can make our front end fast and very dynamic. Save this file and open NBR component. And at the first link, we pass as popular. And for second link, we pass has top underscore rated. And at last link, we pass as upcoming. Save search and Gs and take a look. Click on top rated Link and C our page scroll at top rated section. Now, if we click on upcoming our page scroll to upcoming section. But this is very sudden scroll. Let's make this more realistic. So pun index dot css file. Here we add styles for SDML tag, curly brackets, scroll behaviors to smooth. And that's it. Yes, we don't need to do any other thing. Save the ings and take a. Click on A link and see, we get this smooth scrolling effect. And also, our filter and shorting features are working well with individual components. So this application looks very simple, but it has many real world features which will make our application modern and easy to use. So congratulations. Here our project to movie maniac is completed. You can see react is very easy and simple to use. Just you have to master some basic concepts like components, state, props, and some RM methods, and you are ready to go. And one more thing, watching only course will not help you to create application on your own. Have to code along with me, or you can watch one lesson and then write code by your own. By this method, you will understand react better, and your logic building will also refine with time. If you have some doubts, then you can ask me in the Q&A section. I love to answer your questions, and I see you in the next section. 76. Section 08 React Routing: Welcome to Section eight of the ultimate react course. In this section, we are going to learn about routing, which is the very important concept of react. If you are going to work on any big react projects, then you definitely need to add react routing in your project. We will see multiple routes, single pace routing, route parameters, query string, nested routing, navigation, and much more. After completing this section, you have a solid understanding of how routing works in react. So let's start this section. 77. Setting up Project: Now, let's set up our new project because we don't want to mess up our project too, and also we don't learn all concepts of routing in that project. After learning that, we will add routing in our project too. So in the resources folder, you get one folder called routing template. Open that folder and open it in VS code. So previously, we are building our project from scratch. Now, this is the way you can use other react projects and start working on them. So we open our terminal by pressing Control plus backtick or Command plus backtick. And simply right here, NPM run Dow and hit Enter. And here we get this message. White is not recognized as an internal or external command. Why we get this message? The reason is we don't have node modules in this project. Now, how can we add node modules? By using NPM install and hit Enter. This command will run all packages and library we used in our project. In other words, it will install all dependencies with available versions in our packet sn file. And that's why packet JsnFle is more important than non modules. Now we can run NPM run Dov. Sorry, I make typo here. Let me NPM run Dow. Open this URL and see here we get our application. Let's see what I add in this application. So in the app component, we have NaBr at the top and one main tag for our application. In this main tag, we want to perform all routing. Now let's see what is inside this NaBr. You can see this NaBr has only one order list with four list items. And inside these, we have simple anchor tag with HF and mentioned different links here. 78. Adding Routing for React Application: Now, before implementing routing, let's first understand what is routing. So here we have a couple of anchor tags. If we click on any of the link, we will redirect to that link. See, in URL, we have local host, call on 5173 slash ArtCLS. So when we on Articles URL, we want to show Article page, and that we'll call routing in simple words. If we click on Products Link, we want to display products page. This is very common feature of any website. In our both projects, we did not add routing because our application has only one page. But if we create another project and we need to add other pages, then we need routing. So as we know, react is Ja Script library, and it has no feature for implementing routing functionality. For adding routing in our application, we will use one external library called React Router Dom. This is one of the most popular library for handling routing. So open up terminal and add new terminal and write NPM install, React router Dom. If you want to install the same version which I am using, then you can add here at the rate 6.11 0.1 and hit Enter. So if in future react Router Dom gets updated in major way you can still follow this code. Now to add routing in our application, first of all, we have to wrap our application with one browser router component available in react Router Dom package. So penmin dot JSX file, and at the top, we import Browser router from react Router Dom. That I'm not writing the full name, I'm just writing first letter of that library, RRD, and hit Enter. Now, before our app component, we had browser router component and move this closing tag after app component. This browser router component is very important because without that, routing will not work. Also this component keeps a record of current URL and navigation of our history. Don't worry. We will see that history in upcoming lessons. For now, just remember without this browser router, our routing will not work. Save this file and back to our app component. Here we will define our routing. So first of all, we add here one component called route. By using these, we can define on which page which component should display. Don't worry, see this. So first of all, we want to define our home component, and here we add our path which is home. So we only add here slash Now, which component we want to display. We want to display this home component. So we add element attribute equals to in CL brackets, we add home component. Here we can see auto Import is not working. So here, we have one more extension for that. Open extension panel and search Auto Import and open this second extension. Note this name, you have to install this same extension. Let's close this extension tab, and again, right here, home. See, now we get Auto input. So this route line will tell our application if browser URL is this path, then display this element. Simple as that, save the changes and take a look. Open up Console, and here we get error. A route is only to be used as the child of routes element. Please wrap your route in our routes. So it clearly say to wrap our route component with routes component. So at the top, we import routes after this route. And before our route, we add routes component. Move this closing tag after this route, save the inches and take a look. A, here we get our home component on the index page of our application. Now let's set other routes. Duplicate this route component three more times. For first, we change path to slash products and element to products component. See what Import is working properly. Path to articles and element to articles component. And at last path to slash admin and element to admin component. Save the changes and take a look. See, first we are on home. Now click on Products Link. We get products, articles, and admin. So it is working good. Now you might ask why we define our routes only here? Can we define routes at other place? Yes, we can define our routes at whatever place where we want to display routing. Example, we create one E Commerce website, and we want to add routing in that project. This website has different section like Navbar at the top, footer at the bottom, left side panel for displaying new products, and one main section. Now in the Navbar, we have a couple of links like mobiles, laptops, watches, clothes, et cetera. When we click on any of these links, we need to open that page in this main section. Other parts of website will stay same. Just this main section gets changed. So within this main section, we have to define our routes and that exactly we did in our routing project. In short, just remember that in which part we define routes, only that part will change when we redirect to another page. 79. Adding not found page: Now in our application, user wants to redirect on URL like slash profile. So if our project has no profile page, you can see here we get nothing, which is fine. But we want to display the 40, four not found page when user redirect to page, which is not defined in our routes. So let's see how we can do that. So after this all routes, we add one more route component. And we pass path equals to star, which means whatever path which is not available in these other routes, and we pass element to not found component. Now, let's see what is inside this not found component. See, I just add tag with 404, page not found text, and add color to red. So back to our app component, save the changes and take a look. See, here we get 404, page not found message. You can add custom styles to this not found page. It's totally up to you. Now, if we go to homepage, we get our home, and if we redirect to any other URL, let's say ABC, then we get 404, page not found. 80. Making Single Page Application: Now in our implementation, we have little issue. If you notice, when we click on any links, our whole page get refresh. Let me show you. Open developer tools and go to NetworkTab. Now click on Anink and see here we are making this 21 request. But we know that react wraps all the code in one bundle file, and then browser will fetch that code according to its need. We don't need to send full bundle for each page. Example, if we use YouTube, YouTube website will load only for time. After that, if we open a video, then it will just load the necessary part, but it don't gets refreshed again. This type of application are called as single page application. So let's make our application single page application, which is the most common features of any modern websites. So for that, we open our Nebr component and at the place of this anchor tag, we add one component called Link, which we get from react router doom. See it autoiputed on top. Let's also replace these anchor tags with this link component. Now, at the place of this HRF, this link component has to attribute. Select this hf and press Control plus D or Command plus D and replace this HRF with two. Without these two attribute, this link component will not work. Save the changes and take a look. Now click on any Link and see we are not making all SGTPRquest and also our websites don't get refreshed every time we open Link. So you can see how simple it is to make our application single page application. Just we have to use Link component at the place of anchor links. Sometimes we want to highlight the current route link, which means if we are on products page, then we will highlight its link, so user will know which page he or she currently on. It is really simple. Replace this link component with another component called Navink let's remove this link Import. We don't need it. Save the genes and take a look. It works the same as before. Now let me show you something cool. Inspect this link and see if we select products link, we get here active class. So whichever link is selected, New Bar component will add active class to that link. So by using CSS, we can change its style. So in our navbar dot CSS file, we at dot Navbar, list, anchor dot Active Cali Brackets, font weet to 500 and color to blue. Save the changes and te galec. See, here we get our articles link highlighted. You can see how smooth it works, and that's the power of react router dom. 81. Route Parameters (useParams): Now, sometimes in our application, we need to use route parameters. Let me experi you with the example. So here we have our products component. Now let's set some links into this component. So after this AHT tag, we add one unordered list, and inside this, we need Li, and inside this, we need link component. And here we pass attribute two equals two in double codes products. We want three ally with link inside. So we wrap this Ali anchor tag, link with parenthesis and multiply it with three and press tab. See, we get this MT. I know this is a little complicated, but it is just a time of practice. The moment you get bored with typing repeated code, you will try to use METs and shortcuts for that. Let's pass here product one, press tab, product two, tab and product. Now we want to add in this link path ID for each product one, slash two and three. So if we open products s one, which means we want to see product which has ID one, or whatever parameter we pass here. This is the common structure of routing, and this is called as route parameters. By using this ID, we will fetch details about that particular product and display that details on our web page. Save the changes and take a look. Go to products page, and here we get error. So open Console and see, here we get ink is not defined. So back to VS code, and here we import this link component. Save the changes and take a look. Click on product one, and see, here we get 404 page not found because we forgot to add route for this link. So back to app component, and here after this products route, we add one more route path to slash products, slash colon, and now here we will add our route parameter name. Let's say ID. Note that we are just passing here one route parameter because we need only one. But we can also pass as much route parameter we want. Just remember if we want to add route parameter, then we have to use colon at the beginning. Otherwise, it will not work. Now element equals to here we add single product component. Save the changes and take a look. Click on any product link and see we redirect to single product component. So it's working. Now you might ask, what is the purpose of this route parameter? We are getting the same page for every single product. Let me show you that. A task is we want to get this ID in this single product component. So on a single product component, and for fetching the route parameter from URL, we have one hook in react router dom. So at the top, we input use params from react router dom. Params stand for parameters. Now in our functional component, we call this use params hook and this hook automatically return the object of route parameters, and that's it. We don't need to do any other thing. Let's store these in variable called params. And after that, simply console dot log these params. Save the changes and take a look. Open up Console. And see here we get route parameters in object. Remember, this property name is same as we describe in our route here. Now, in the real world application, by using this ID, we can fetch data from our back end and also do many more things. For now, let's simply display this ID here. So we destructure this object and get here ID. Now remove this console and let's print this ID after this heading. Save the changes and take a look. See if we go to product two, we get single product two. And if we go to product three, we get single product three. So that's all about route parameters. 82. Query String: Now, let's type of URL parameter, which is squary string. Of data, we want to pass with our URL request. Let me give you an example. So here page. Imagine we have list of articles and we want to short that article by date and category to electronics. These are the data we want to pass in our URL. So here we pass in the URL, question mark, and after that, whatever we pass here goes as query string, and we can get that variables in our article component. Another most common example of query string is search. Let if something on YouTube. Notice the URL changes to results, question mark, and here we get query string. If we cause URL and paste it in another tab, we get the same search result. So that's the work of query string. So back to our example, we want to pass here to query string. First, we write our variable name, short by equals to now without any codes, we pass here our value. Let's say date. Now to pass second parameter, we use person category equals to electronics. Now, let's see how here. I know this is a little bit boring, but these concepts are very important when we are working on any big open up article component, and at the top, we need to import one hook for getting query string parameters. Use search peramsRrouter doom. This use search params is very similar to our use state hook. We call this hook here in our function. And pray with two items. So we store that in variable and using R destructuring, we adhere search params, comma set search You can see it is very similar to use State Hook. Now in this first property, string parameters. And by using the set search params, we can set query string parameters. Let's first see search params. This search params has one method called GT. And in parenthesis, we have to pass our variable name. Let's say short B. Make sure we write the same variable name which we pass in query string, and we store these in variable called sort B. Now, let's duplicate this line by using saved plus lt plus down arrow. Plus option plus down arrow and change this shot by to category. Now, let's print this here. So cul brackets, shot by, and after that, cul brackets category. See the changes and take a look. See, here we get these two query string variables. Now, let's see how can we use set search perms for setting query string parameters. After this AT tag, we create one button called shot B views. And also, we pass here on click and inside it, we pass function, handle, short, B. Now, let's define this function. So const handle shot by. Arrow function, and here we use set search perms and here we need to pass query string variables in key value pair. Sort by and value to views. Whatever object we pass here, it will set as query string. Save the changes and take a look. Click on this button and see in the URL, we get query string to short B equals to views, but our category is gone. In this object, we add one more key category and value to this category variable. And as we know, if key and value same, then we can remove this. Save the changes, and take a look. Go back to our page and again click on this button. See, here we have our query string. You can see how simple it is. 83. Nested Routing: Now let's imagine this admin page as admin panel of website. On this page, Admin can view all sales details and all sellers details. So admin component in this, we want to add two link components. So underlysed inside it, we need Ali and inside it, we need link component with attributes two equals to admin, and we wrap this Ali and link component with parentheses now for first link, we add sales and Link also slash Sales. Second link sellers and sellers and make sure to import link component from React Router doom. Save the changes and take a look. If we click on sales Link, it will redirect us to Admin Salespage. But here we get page not found. Here we don't want to open new page. Instead of that, we want to show the sales page within this admin panel. Something look like this. We click on sales page, then sales page will open below this admin panel. And if we open seller's page, then that page also display here. So imagine these four links are our horizontal bar, and these two links are our side bar. This routing is called as nested routing. So let's see how we can add nested routing. So app component now to define nested routing, we need to wrap our nested routes into route. So at the place of this self closing tag, we add separate closing tag now between these, we need to define our nested route. So we add another route path. Here we pass our nested route path. So if you want to define slash admin slash sales, then here, we only need to write sales because slash admine is already here. Now element to sales component. Now let's duplicate this code, and at the place of the sales, we pass sellers element to also sellers. Save the inges and take a look. Now if we click on sales Link, we don't get 404 error page, and also we get this admin panel on both these pages. Now, why we don't get our sales and sellers component. So for that, we need to follow one more step. So admin component in which we want to display this NASDARouting. And here we have one component which specify at which point we want to display NASDA routing. So at the top, we input outlet from react Router doom. And where we want to display our nested routing right after these two links. So here we add our outlet component and that's it. Save the changes and take a look. See, here we get our pages. Both pages are working well. So let's recap this lesson. So for defining nested routing, we will wrap our sub pages with main route component. In this case, it is add now, whatever we pass in this element will display in this both page. If we don't pass here this element, then we will not see that element on these pages. This is called a SAD routing because we are displaying one page within another page. And for displaying SAD routing, we need to pass outlet in this admin component, simple as that. Also, this nested routing is not very common for react application. Only sometimes we need that, don't worry about that. Now here our app component looks a little ugly because of this all routing. So let's store this routing in separate component. So we cut this all routing, and in our source folder, we create a new component called routing dot GSX. We add boilerplate code, and at the place of this DU, we paste our routes. Now, let's also cut all input from app component except this Nabriput and paste it in the routing component. Also, let's cut this routes and route component from here and paste it in our routing component. Save this file and back to our app component. Let's add here all routing component. Save this and see now our app component looks clean. 84. Programmatically Navigation: Let's see another important feature of routing, which is navigation. So imagine when user visit this admin panel page, we want to check if user role is admin or not. So here, first of all, I close all other files, and here we define one object called user equals to object and pass here property role and value to let's say user. This is just for example of navigation. After that, we can pass your condition like if user dot role is not equals to Admin, then we will redirect this user to homepage or login page. So to navigate, we have one component called Navigate. So at the top, we import Navigate from a router doom. And in this I blog, we simply return this navigate component. And inside this component, we add attribute to equal home path, and that's it. Make sure to return this navigate component because when I'm recording this lesson, I forgot to return it and waste a lot of time for finding this error. Save the changes and take a look. Try to open Admin panel and see we directly redirect to homepage. Now there is one more way to navigate. So here, when we go to single product page, we want to add here go back button. Open single product component. First, we add here button called go back and add here event on click equals to handleba. Now, let's define this function. So const, handleba, arrow function. And inside this, we write our navigation logic. This called as programmatical navigation. So for that, we need to use one hook called use Navigate. So at the top, we imput use Navigate hook now, inside this component, we call this hook, and this hook give us navigate function. So we store that invariable generally called as Navigate. And inside this handlebag function, we simply call this navigate function. And inside this, we have to pass our path. So here we just pass minus one. If we want to navigate to specific page, then we can write something like this. Slash articles. Now, let's change this to minus one, save the changes and take a look. See, when we click on this button, we go to our previous page. So that's how we can navigate to different pages in our important features of react router dom. If you want to learn more about that library, then you can read its documentation. But to create modern react applications. If you have some doubts, then you can ask me in the Q&A section, and sorry about these routing project styles because I want you to understand important concepts of routing without worrying about styles and looks of application. Developers don't know, so feel free to ask question about that. 85. Exercise for Routing: Now it's time for routing exercise. So in our previous movies project, we have no routing. So your first task is at routing in this project. Route should be like this. At homepage, we will by default show popular movies list. Now when we click on top rated movies, we will redirect to top rated Route, and if we click on upcoming link, then we will redirect to upcoming page, and upcoming data will display. At the navigation bar, you can also see the active route. Now, after that, your second task is when we click on any movie card, it will redirect to movie slash its ID. Don't worry about that page. You have to display the movie ID on that page. No styles, nothing. Just simple text. Just practicing the routing here. If you want to add this project in your portfolio, then make sure you duplicate this project and then complete this exercise on duplicate code. So spend 15 to 20 minutes on this exercise and feel free to rewatch these lessons of particular part. It's completely fine. The goal of this exercise is to go through basic routing concepts. So see you after completing this exercise. 86. Adding Routing to Project 02: I hope you try to solve this exercise because trying to solve this exercise indicates that you really wants to learn react. So if you even try, then appreciate yourself for that. Now, let's see the solution of our routing exercise. So first of all, I'm not going to interrupt our old project. Instead of that, we will create duplicate project. So copy this all files, except node modules and package dot log dot GCN file. And in our project folder, we create a new folder called routing exercise. And inside it, we paste our files. Now, let's open this in VS code. Good. First of all, let's install all our project dependencies. Open up terminal and write here, NPM install, and hit Enter. What will this command do? Write. It is for adding and installing node modules folder. After that, we need to install one more library for routing, which is react router dom. Write NPM install, react router dom, and hit Enter. It will take some time, good. And at the end, let's run this application with NPM run Dow. And open this link in our browser. See, it's working. Now, let's start with adding routing. First of all, we need to decide in which part we want to display routing. So we need to add routing after our NaBr component. But before that, we need to wrap our whole application with browser router component. So in the main dot JSX file, we import browser router component from Rag Router doom, and let's wrap our app component with this browser router component. Save this file, and let's define our routes. In the app component at the top, we import routes and route from Rag Router dom. Now here, after this number component, it's better to add main tag, and in that tag, we will add routing. So first of all, we add routes component, and inside these, we add our route component. I'm going a little faster because we see these already in this section. So in this route component, we have path, and first we define path for whom, which we can add a forward las element to here we simply cut this movie list component with popular title and pass it here. Now, let's define another route, and we set path two slash top underscore rated and element to this movie list with top rated component. And at last, we define another route with path upcoming and element to this movie list with upcoming component. Physically, we are telling on this path, display this element. React don't care about we are rendering the same component or not. Save the changes and take a look. See, on homepage, we only get popular movie list. Now we change our URL to top underscore rated and see we get top rated component, so it's working. Now, let's highlight these Navbar links. So open Nu Bar component and at the place of this anchor tag. What component we will add? Right, it is Nowlin component, and see it is autoiputed at top. Now also replace this with New Link, and also this last one. After that, at the place of this all HRF, we add to attribute, select HF and using multi cursor editing, we replace this all HRF with two attribute. Now for first link, we pass HomeLink, which is forward slash. For second, we add slash top underscore rated, and for last link we add slash upcoming. Save the genes and take a look. If we click on this popular, we get popular title. And if we go to top rated, we get here top rated title, but movies are not changing. So let's fix this really quick. So in our movie list component, we are fetching data in this use effect hook. And as we know, this use effect hook will run only one time when that component gets rendered. And in our case, this component fetch data from API when we are on popular page. But if we change our page to top rated, only the type title and emoji properties are changing. And that's why this use effect will never run again. So to solve this issue, we have to run this use effect hook when these type props is changing. So here we simply pass type independency array. If you are a little confused, then don't worry. In the next section, we will see these concepts in details. Save the changes and take a look. See now our movies are changing according to its type. Now, let's inspect this link. And here we can see active class. So we just need to add CSS for this active class. So one Nabar dot CSS file. And after this Naba links anchor, we add Nabarlink angle bracket, anchor dot Active. And in Gali brackets, we add font weight to 700. See the changes and take a look. See, here we get highlighted ink. You can see how simple it is to add routing. Many developers made it very hard because they try to do everything in single step, but always try to do any implementation step by step. 87. Defining Route Parameter for Single Movie: Now here, when we click on any of this card, we don't want to open TMW Link. Instead of that, we want to open another page on our website, which can display our movie details. So let's change this link first. Open movie card component. And at the top, we import Link component from React router Dom. Now at the place of this anchor tag, we add link component and we can remove this target attribute. We don't need it at the place of this HF, we add two attribute. Also, remove this DMD base URL. We just keep slash movie ID, save the changes and take a look. Click on any movie card and see, we redirect to movie slash movie ID. So our half task is done. Now we want to just display this movie ID on this page. But before this, we have to define this page route. So app component, and here at the bottom, we add one more route component. Path equals to now what we pass here? Write movie slash column. And here we add our variable name, ID or movie ID. I think that is more specific. Now, element, here we want to add new component. So in our components folder, in our movie list folder, we create a new component called single movie dot jsx. Now, let's add here our boilerplate code. Nice. Save this file in our route. We add single movie component and auto Import works. You can see how fast we can write our code using auto Import extension. Save the changes and see here we get single movie component, so it's working. Now, let's simply display this movie ID so do you remember what we will use for that? Right? We use use peramsHok from react router dom. So back to single movie component in the functional component, we add use perams and select this suggestion and it will get auto input. Here we call this hook, and this will return route parameters object. So let's store these in variable, call params, or we can even destructure this and add here movie ID because in our route, we define our route variable name to movie ID. Now at the place of this DU, we add to tag and right here, single movies in curly brackets, movie ID, and that's it. Save the changes and take a look. See, here we get our ID. I hope your all doubts related to routing is clear now. There are always updates or different syntax for writing code, but the core concepts will never change, and that's what I want to teach you. Once your core concepts are clear, you can learn new concepts and syntax quickly. If you are continuously watching this course, please give yourself a little break and get some fresh air and I will see you in the next section. 88. Section 09 Calling an API: Welcome to the Section nine of the ultimate react course. So as we know, react is used to build front and part of our application. In real world, we also have backend, which runs logic and store data in database and also used for authentication. If you want to work only as react developer, you don't need to learn backend such as no Js, jango or asp.net core. But you need to learn how we can connect our react application with backend. And that is we are going to learn in this section. So let's dive into this. 89. useEffect hook in detail: Before we start calling an EPI, first, let's properly understand what is use effect hook and how we can use it. So SILuusefect is used to perform side effects in our component. Side effects are actions which are performed with outside the world. We perform a side effect to reach outside of our react components to do something. For example, fetching data from API, storing data in the local storage, which we see in Project one, directly updates the dome and timer function like set timeout or set interval. These are the most common side effects in react. So to perform any kind of side effects, we need to use use effect Hook. Now let's see how this use effect works. In this section, we will use our previous routing project because creating a new project for each section is little tedious. So here, in this seller's component, first, we import use effect from react, and after that, we call this use effect in our functional component. Now, as you know, this use effect hooks takes two arguments. First one is Colbek function in which we perform our side effects, and after that, we have dependency array. For now, let's don't pass this dependencies array and inside this callback function, we simply write console dot log component mount. Save this file and take a look. Open up Console and go to admin page. See, we redirect to homepage because we have to set a user role to admin. So in admin component, we change this role to admin. Save these and now try to open admin page and go to Seller's page. Here we can see we get component mount. We get this console two times because of react mode, which I told you before. React Stit mode, render our component twice in development process. Now, this use effect will run on every mount and re render. But let's first understand when our components gets mount or render. So component mount is when our component gets display first time on our browser. Now, after our component mount on our browser, if something change or update in that component, it will cause rerender. So if we don't pass any dependencies here, this Colvec function will run on component mount and rerender, which means when something change in the seller's component, simple as that. So let's say this live. Here, we have nothing to see re render. First, we add here react fragments because we are going to add multiple elements. Now let's add one input box for handling its value, we create one state variable call name and set name and pass empty string as default value. We've done this many times, right. Now here we pass unchanged event, and here we get event object, arrow function, and set name to its current value. So how can we get current value? Right? By using event dot target dot value. Simple. Save the changes and take a look, refresh this page, and here we can see we get component mount, now we write something in this input and you can see, we again get component mount. Now again, if we write something and C, we get component mount one more time. Let me explain to you what is happening here. After our component gets mount, we write in this input box, which will change this state name in our component and that will cause render and because of that, our use effect will run. Whenever we want to run some code on mount and render we use use effect without any dependency. Now in this next lesson, we will see other two varieties of use effect hook. 90. Dependencies of useEffect: So in the previous lesson, we see how we can run function on mount and re render. Now, sometimes we want to run our callback function only one time when our component gets mount or display on browser. It is really simple and easy. Just we have to pass here dependencies array as empty array, save the changes and take a see, here we get first time component mount. After that, if we change anything in our component, that use effect will not run. By using this ETR dependency, we will get data from API because we just want to fest data one time, which we already done in our project too, right? Other example, suppose we call one API, which will return the number of notification, so we can change our web page title according to that number. First, we store domain notification number to five and after that, here we write document dot title equals to in CTI, we add dollar C brackets, notification, and after that, new notifications. Save the changes and take a look. See, here we get custom notification title. This is how many react application display dynamic title. Now suppose at the place of this notification, we want to display this name state. Here, we write name and dollar Cali brackets. Here we add name, save the changes and take a look. Fresh the page and see here we get only name text because currently our name is empty string. But if we write something in this input, we don't get that name on our title because this use effect will run only one time because of this empty array. But here we want to run it whenever this name variable changed. So here we just pass name variable in this dependencies array. Can also pass here multiple variables, save the changes and take a look. You can see now our title has updated name, so that's how dependencies work in use effect. 91. useEffect clean up function: Now let's see the last and important concept of use effect Hook. So sometimes we need to add cleanup function for removing side effect. For example, here we are only updating the title. Now imagine here we are subscribe to chat room, and if we move to another page, we want to unsubscribe to that chat room. So for unsubscribing the room, we need to use cleanup function. Know this example is a little difficult to understand. Let me simplify for you. Imagine this is our chat component in which persons are chatting. When two persons are chatting, both person needs to subscribe or connect to the same room ID. Because of that, both person are getting the message immediately on their screen. But if one person left the chat room, then we have to unsubscribe or disconnect from that room so that person will not get message on their screen. In most cases, we don't need to use cleaner function sometimes we have to, and that's why I want to show you this. So here, let's remove this unwanted code, and we again add console dot log component mount. And at the end of our callback function, we want to add cleanup function. So here we return one function. And in this function, we can write our cleanup function logic. This cleanup function will run when our component gets unmount or removed from screen. So here we simply write console dot log component unmount. Save the changes and take a look. Refresh the page, and here we can see first, we get component mount, then component unmount, and again component mount. As I told you, because of react street mode, our component gets rendered two times. So first, it will mount, then react street mode, remove that component, and that's why we get here component unmount. And after that, our component mount again. Now, if you go to any other page, here we get again component unmount because our component removed from our screen. So that's how cleanup function works. Don't worry about that. We will only use cleaner function hardly one time in our application. So to quickly recap, usefect is used to perform side effects in our component. US effect has two parameters, first, callback function and second, dependency array, which is optional. By dependency array, use effect has three variations. First one is without any dependency, which runs this callback function on mount and every re render. Second one is empty array, which runs this Calbeck function only on mount and last one is dependency array with variables, which runs this Calbeck function on render and also when any of these variables will change. One more thing, as we add multiple use state hook in our component, we can also add multiple use effect hook in our component, simple as that. No I repeat this use effect hook many times, but I just want to make sure you have the right fundamentals of use effect hook. And also, I want to explain mount, rerender, and unmount, which called as component life cycle. So you learn both concepts using single lesson. 92. Basics of HTTP Requests: Now before we call API, let's see what is SDDPRquest. So as we know our client, or we can say if our browser wants some resources, so it will request server using Internet. This request is called as SDDPRquest. So in simple words, this SDDPRquest is worked like a bridge between clients and servers. Now, when server receives SDDPRquest, it will return some resources, which client request for. Example, previously we set STDPRquest for getting the movie data. So TMDB server takes our STDPRquest and then send us response simple as that. Now, there are some methods which describe which type of task we want to perform. So first, we have Get request, which is used to fetching data from server. We already seen this right. Next, we have post request, which is used to submit data to server, like signup form or login form. Next, we have put request, which is used to replace the data at server. After that, we have patch request, which is used to update specific data at server. Now you might ask, what is the difference between put and patch? For example, we have server which have information about ten books. Now, if we want to replace this one book with new book details, then we use put request. But if we want to update a specific details of book, like we want to update its price, here we are not replacing the entire book details, but we are just changing the specific part of this book details. So in this use case, we use patch method. And last, we have delete method, which is used to delete a specific data. We are already making this request when we are using any websites, and we use Get request many times a day. For example, we open website udemy.com. Here we are sending request to get webpage from server, so that server returns this web page as response. Here we are using GetRquest without knowing. Now in the next lesson, we will send Get request for getting data from server. 93. Fetching Sellers data: Now let's start with getting data from API. I know you already know that, but I want to revise you and also without getting data, how can we perform update or delete functionality? Let's quickly get data from API. Here we will use fake API, which will work the same as original API, which you will get from Bend developer. Head over to Jason placeholder.typicod.com. This API is built for tasting and learning about calling an API. Roll down to the bottom, and here we can see different kinds of data, post, comments, photos, to dos, et cetera. We are going to use this user's data. Open these and here we can see we get this different users data. We will consider these users as sellers for our project. Copy this APIURL and back to VS code. We don't need this use effect, and let's add use effect from scratch. So use effect, callback function, and here what we add dependency array with variables or no dependency. Right, we will add empty array as dependencies because we only want to get data one time from API. Now inside this callback function, we will call our API for getting data. Now, previously, we used fetch method for calling API in our second project. But now we will use the most popular library for calling API in react, which is XOs. So open up terminal and add new terminal, and right here, NPM install AXOS and hit Enter. Don't worry about Axios. It is more easy to use than fetch method. Now at the top, we input Axios from Axios package. Now in our use effect hook, we write Axios dot. Now here, we have to add our SDTP method, which is get for fetching the data. Now inside this function, we have to add our API in codes, same as we did in fetch method. Now this expression returns a promise. So for handling, promise, what we can use, write. We can use then method or acing await. Here we write then and we get here response, arrow function, and we simply consult dot log this response. Save the ginges and take a look. Open up Console. See, here we get this response from API. Let's see this request in more details. So here we open Network tab. For now, we don't get any request. Refresh this page, and we can see bunch of requests for documents and scripts. But we only want to see the fetch request. So here we select Filter, fetch or XHR, which stands for XML SDDPRquest here we get two users request because of react Street mode. Here we can see status code to 200, which means successful size of our request, and we have time for completing that request. These are details about this specific STTP request. Let's see what is inside this. Here we can see headers of this SDTP request. So every SDTP request and response divided into sections, header in which we define metadata, and in the body, we define or get the data. So here we can see some general header details about our SDDPRquest. We can see here URL, method, status code, remote address, which is the IP address of client. Now, after that, we have response headers which server sends with response. Most of the time, we don't need to worry about that, and at last, we have request header. Also, we don't worry about that. Now in the preview tab, we have the preview of our data. And in this response tab, we get our data in structured way. Now, let's back to Console. And here we can see in this response object, we are getting this config data in which we get our data, headers by XOs request status 200, which is for success and status text. Most of the time, we are only dealing with this data. So let's display this list of data on our seller's page. So for displaying the data, we have to store it in one state. So we create one state variable called sellers and set sellers and pass here empty array. Now, at the place of this console dot log, we pass Setsellers function, and inside this, we pass response dot data. Now, let's simply display that sellers. So in Ci brackets, sellers dot Map, here we get each seller and we return a paragraph tag and pass here seller dot name. And as we know, for map method, we have to also add key attribute. So key equals to seller dot ID, which is unique for each seller. See the changes and take a look. See, here we get this seller's name. You can see by using axios, we don't need to do one additional step, which we did in fetch method. I hope your all doubts about G method is now clear. 94. Adding Loading Indicator: Now, when we send requests to server, it will take some time like half second or less. But sometimes if our data is large, or user's Internet connection is slow, then we have to display loading indicator on our web page. So at the top, here we create one state variable called Ioading and set Iloading. As default value, we pass false. Now in our use effect hook, before we start patching data, we set is loading to true. And after we get our data, which is in this then method, we add here code block, and in new line, we set loading to false. Simple as that. Now, before our map method, we can add culipracket and add here condition if his loading is true. Then we display here ST tag, and inside, we add loading text. Save the changes and take a look. Refresh the page and see here we get loading tags just for milliseconds because my Internet connection is fast and also data size is small. Now, let's make our Internet slow. So in the networks tab, here in this trotoning we can select fast three G, slow three G, also offline. So let's select slow three G and repress the page. You can see here we get this loading text, so it is working fine. Now sometimes we want to display loading indicator for whole page. For example, here we display data and also we have input S three tag. We only want to display loader when the seller's data is getting fast. But sometimes we want to display loader for whole page. For that, we simply addhe if condition before this written and condition is same. If I loading is true, then we return this ST tag with loading Save the changes and take a look. Refresh the page and see here we get this loading text for this whole admin centers page. For now, we don't need it. So let's remove this if condition and save this file. Now let's quickly add loading spinner at the place of this loading text. So head over to loading dot IO slash CSS. From here, we have 12 basic free CSS loaders in pure SDML and CSS. Let's suppose we want to display this loader. Click on it, and here we get SDML markup in the bottom and CSS styles at top. Copy this STM markup, and in the components folder, we create one more folder called Common and inside these, we will create a new component specific for loader. The reason we add this loader in this common folder is this loader is not specific to only admin page. We can use loader in different pages. It's totally depends on us. First, here we add boilerplate and paste here, our SDML markup. And at the place of this class, we will add class name. Now at the top, let's import CSS file loader dot CSS. And for that, we create a new file in common folder, loader dot Css. Now back to browser, copy these styles from here and paste it in the loader dot css file. Now we can see currently our loader color is white. We can change it from here. Let's change to a CD CD CD, which is gray type of color. Save this file and also save this loader component. And now let's display this loader. The place of this loading text. Remove this and add here loader component. Save the changes and take a look and see here we are getting this loader after this input. Let's move it in the new line. So here we can simply wrap this loader with Du. Save the changes and see, here we get loader in new line. This looks pretty nice. 95. Handling Errors: When we are working with API, it's important to handle errors because if users Internet connection is gone or they try to get unwanted data, we have to show them error. Now, before this, here I notice something. Instead of wrapping this loader component in Dieu, we can add loader JSX element. So pen loader component, and here we wrap this die with another du. Save this file and back to seller's component. Here after this loading state, we add one more use state variable called errors and set errors. And here we pass empty string as default value. Now, as you might know when we are working with promises, we can use catch method for error handling. Let me show you. So after this then method, we add cache method, and here we get error object, error function, and let's simply console dot log this error object. Basically, when we have error in this promise or in this then method, we get that error in this error object. So let's make one typo here in API, save the changes and take a look. Open Console, and see, we get error object with a bunch of details. In this message property, we get the error message, and in this response, we get error message from server. Currently, this JCNPlaceholder API is not sending any message, but if we have our own API, then it may return our custom error message. Let's display this message on our screen. Here, we add cod blog, first, we want to set is loading to falls because even if we get error, we still want to make loading to falls, and at last, we set errors to error dot message. Now, let's add condition after this loader. If errors are available, then we return emphasize tag, and here we simply display errors variable. Save the changes and take a look. See, here we are getting this error. Now, let's remove Tipo from API URL, save this file, and see here we get our data. So it is working well. You can see how simple it is to display loader and errors with API call. Just we need to understand the basics. 96. Promise with async await: Now, let's quickly see how we can handle promise and errors with a sync await. So for now, I comment out this code, and after our use effect, we create a new function called fetch sellers, error function. And inside this, we add this expression from here. And also at the top, we add set is loading to true. Now, as we know, this expression returns our promise. So we add here await and for using await, we have to make our function async. Now, let's store this value in variable called response. And after that, we simply copy our code from then method and paste it here. Now, let's call this function in use effect. Save the changes and take a look. See, it's working. Now let's see how we can handle error. So for handling error in as a wait, we have to use try and catch block. So we write try catch and select this suggestion and see we get this try and cache block. This is the power of ES seven extension. Now let's move this code in Try block and move this set es loading outside of this block. Now in catch block, we simply copy code from this catch method. We change this error attribute name to error. So in simple words, if something went wrong in this dry block, then this sketch block will run let's make one typo here, say the changes, and repress the page. See, here we get this error. So that's how we handle errors and promise in async Awit. But here we can compare this both code. We can see our previous code looks more maintainable and more organized than this async avid. In our movie maniac project, errors, and that's why our code looks more simple with a zincavt. So for the rest of this section, we will use this band method. You can use whatever you want to totally depends on you. 97. Adding New Seller: Now, let's see how we can add or create new sellers data. So first of all, after this input, we add one button called Ed seller. Also we add here on click event and pass here function name, add seller. Now let's define this add seller function. So const, add seller, arrow function, and inside this function, first, we have to create new seller object. So const, new seller equals to object. And first of all, we have to pass name and we set to this name state. Here key and value, both name are same, so we can remove these. Here, we have to also add ID because we are adding this ID as key in our list. So here we set ID to sellers array dot Length plus one. Now there are two ways to handle data on website while we are sending or updating data using API. First, we can update our data or UI on browser. After that, we can call API for adding or updating that data. This method is called as optimistic update. Now, there is a second way in which we first call API for adding or updating the data, and after that, we will update our UI. This second method is called as pessimistic update. Almost all modern websites are use optimistic approach because it is fast and more user friendly in compared to pessimistic approach. Example, think about social media website. If you like one post, it should immediately display the like. If we use pessimistic approach, then browser call API for adding like in that post and after that, it will show to user, which one is more fast. Of course, optimistic. Here, we also use optimistic approach. Before we call API, we set sellers to array here, first we add sellers data by using spread operator, and after that, we add our new seller object. Or we can add this new seller object at first. I think that is more beneficial. Save the changes and take a look. Write name here and click on add seller. See, here we get new seller, so it's working. Now, let's call API for adding or creating new data. So we use here axios dot post method for creating the new data. Now let's copy this API from our fetch function and we pass this API here. Now, after that, at second parameter, we have to pass our new seller object because that object we want to add. Note that this post API will not use our ID because ID is always generated by the back end. But here, we're using ID in K, and that's why we add this ID in our object. I will show you that in just a second. So as we know, this expression returns a promise. So we add then method, and here we get response and the response have the new user data which we get from server. Inside this, we add set sellers and here first, we add this response dot data, and after that, we will add here old sellers using spread operator. Save changes and take a look. Write here name and click on add seller. In the Network panel, we can see here new request. Let's see this. And here in header, we have request URL, request method to post, and status code to 201, which is used for successfully created data. Now let's see the payload which we send with API and in the preview, we get user object, which this API returns. Remember that this JSON placeholder API is a fake backend for just learning API. It will always return new user object with ID 11. Let me show you. Again, click on ad seller. Here in the payload, we see ID 12, which we are sending and in preview, we can see we get ID 11. No matter how many records we send, it will always return object with ID 11, and that's why we get error in Console. Children with the same key 11. Now in this API, we have to need to handle our error. So for that, what we use, right, we use catch method. Here we get error object, and first, we set errors to error dot Message. And after that, we need to reset our seller's list to the previous list. For example, here we add new seller. Now, before calling this API, we are setting that new seller in our list. But if for some reason, we get error or we got offline, then we have to restore our list. So set sellers and here we pass direct our seller's array. Save the changes and take a look. In NetworkTab we make our website offline now add name and click on Add seller. See, for just a second, we see our name, but after that, we restore our list to previous list because we have network error. So that's how we make post request. You can see how simple it is. 98. Deleting the Seller: Now let's see how we can delete individual seller from our list. So first of all, we have to add delete button for each seller name. But before that, let's set our application on no throttle link. Now, here in our map function, we wrap this paragraph tag with Du and at the end, we add button called Delete. Save this and we get button for each seller. But this looks a little bit ugly. Instead of showing in Du, we can use tab here. Before this list, we add table and inside it, we want te body. Now let's move our list inside this tea body and at the place of this du we add TR for tableow. And we wrap this both in TD tag. So we add multiple cursor using Alter plus click or Option plus click and add here TD and let's move this closing TD tag at the end. And at last, we have to add key to our parent tag, which is inside this TR tag. The changes and take a look. See, here we get delete button in one line and with same space. But here, we have this extra padding. So in our TD tag, we remove this paragraph tag. We don't want it. Save this and see, we get perfect list. Now, let's add delayed functionality. So here in this button, we add on click event and pass here, delete seller function. But here, we need to pass current seller ID because by using it, we delete our seller. So how can we pass that? Right, we add here arrow function, and after that, we can pass here seller dot ID. Simple as that. Now, let's define this function, delete seller. Here we get ID and arrow function. Here, first we have to display UI change and after that, we will call API for delete. You can pause this lesson and start doing that by your own, or you can follow along. Now, as we know, we use filter method for delete. Sellers dot Filter. Inside this, we get each seller and here we pass condition as ID, not equals to ID. Now this filter method will return a new array, so we can directly pass these into set sellers function. We wrap this with parenthesis and addre set sellers. Now, let's call API fall delay task. Our API should look like this. If we want to remove seller which has IDFi then at the end of this API, we will add pi. Axios dot Delight. Here we add this API in vectis and at the end, we add slash Dollar Calipacket and here we add this current ID. Now, after deleting this, we don't want to do anything because we already remove that object from our list, so we don't need then method, but we need cach method for or handling. So we can copy this catch method from ad seller function and simply paste it here. So if we have any error, then it will restore that seller's list. Save the changes and take a look. Click on delete and see it removed from here. And also, in Network tab, we have one request, and in its header, we have method to delete, and we can see in response, we get nothing. Now let's verify error handling. So we add here one Typo, save this file and click on delete. A, we get error, and our list is also restored. So it is also working. Now before we forgot to remove this typo, let's correct this. 99. Exercise for calling API: Now it's time for little exercise. So as we add Delete functionality, I want you to add update functionality. So for each seller, we have Update pattern, and when we click on that, we will change seller name to name plus updated at the end. Simple as that. Let me give you a little hint. Our Axios expression look like this. We use your patch method because we are only changing one detail. Now this updated seller is the seller object in which we update the current seller name. So I want you to try this exercise because practice by your own will make you better developer. So give it a try and then watch the solution. 100. Solution Updating the Seller: Now, let's see the solution of this exercise. First of all, let's add Update button for each seller. So before this delete button, we had one TD tag, and inside this tag, we add one button called Update. Now, let's also pass OnClick event and pass here function called update seller. And here we want to pass ID. So arrow function and passar seller dot ID. Now, let's define this update seller function. So const update seller equals to here we get ID, arrow function. Now inside this function, first of all, create updated seller object. So const, updated seller equals to object. Now here we want to add all other details about current seller. So at the place of this ID, we need full seller details. So we change this seller dot ID to seller, which is current seller object. Now let's get the seller object here. So now here we can add full seller details by using spread operator. And after that, we will replace name. So name two seller dot name, which is current name plus in double codes space updated. Now we have updated seller object, but we have to replace our old seller details with these new details in our sellers array. Don't get confused, see this. So here we add sellers dot Map. And inside this, we get each seller arrow function, and here we pass condition if as dot ID equals to seller dot ID, which we are updating. If it is true, then we return this updated seller object. Else we writ on the same seller object. Simple as that. Now, let's save this array as our sellers. So wrap this array with parenthesis and we add here set sellers. If you are confused with this direct use, then you can store this array in separate variable and then pass it in set sellers. It totally depends on you. Save the changes and take click on Update and see here we get this updated name, which means it's working. So our half task is done, and now we have to only call API. So here we add Axios and we use patch method and pass here our API. So let's copy this from delete seller function and paste it here. Now at the place of this ID, we at seller dot ID. And at the second parameter, we pass our updated seller. Now, after completing this API call, again, we don't want to do anything, so we don't need then method, but we need cache method. So let's copy this catch method. And paste it here. Save the changes and take a look. Click on Update, and it's working. We can see in response, we get updated name from server. Now let's check for errors. So we make here typo and save this. Click on Update and see here we get error and our list restored with old data. So it is working as well. Now we can remove this typo. 101. Creating axios variable for HTTP Requests: So here, in our application, whenever we are making API request, every time we have to write our full URL, so we can define our base URL for this application. And after that, we only have to write users. Let me show you what I mean. So in this source folder, we create a new folder called Utils. Inside this folder, we create a new file called API ds client dot js for making SDDPRquest using XOs. So inside these, first, we input Xos from XOs. After that, we write Xos dot create now in this function, we have to pass our configuration object. And in this object, we have base URL property. And here, we can pass our base URL. So back to our seller's component and copy this base URL, which is the same in all API and paste it here. If you are working on different project, then you have to pass here you are back and URL. Here, we can also pass our API headers, which we want to send with our API request. Again, it depends on API. Now, this will return instance for calling API. Let's export this as default. Save this file, and now when we want to make API request with XOs, we simply input this instance and do the same as we do with original XOs. So back to seller's component, and instead of importing original Axios, we import API client from here we go two folders up, Utils and API client. Now at the place of the Axios, we use API client. So press Control plus D or Command plus D multiple times and add here API client. Now instead of full URL, we just pass here users. So se this base URL and with multi cursor editing, remove this all base URL. Save this and see it works the same as before. So this API client will work the same as Axios, but we don't need to pass baseURL for all API. And because of features like this, most developers prefers to use Axios instead of patch method. These are the basic concepts of calling an API handling errors and display loader. As react is growing, many library will come into this picture, but the basic concepts of calling an API will remain same. So selecting a library is entirely depends on you. 102. Section 10 - Project 03 E-commerce Application: Welcome to Section ten of the Ultimate react course. From this section, we are going to build our third project, which is E Commerce application. In this project, I tried to cover all important, useful and advanced concepts which you need to apply in real world application. So this is going to be a major project in your portfolio. You can see a beautiful landing page of this website. After that, we have routing and the lead us to the products page. Here we get all products list with infinite scrolling feature. From top, we can also sort our products by price and rating. At the sideware we have a couple of categories, and here we get products only of that category. Now if we click on any product card, we get a detailed product page, which have this image selector, and also here we can add item to our card with the amount of quantity we want. And the beautiful part is this website is dynamic, which means all this data comes from real Ben which I created for this project. Now the moment we add item to card at the Nebr we can see here we get a number of items in our card. Now in the card page, we get the card detail in this simple table. From here, we can also change the quantity of items. With that change, this bill table will get updated and we get the final cost at the bottom. We can check out our order and our CAT will empty, and we can see our order details in the My Order page. So it is a major project, but not difficult project because we will complete this project step by step. Many developers feel major project difficult because they try to build all things in one go. And that's why they feel simple project difficult. So in this project, we will also try to build our UI first, and after that, we will connect our application with the node JS back end. So I'm very excited about this project and hope you are too. So let's dive into this. 103. Setting up Project & layout style: Let's start with the new phrase project. So open your folder in which you want to work open terminal or command prompt in that folder. And right here, NPM, create white, at the red latest, and hit Enter. Now here we add our project name, which is card Wish. You can use whatever you want to. I like this name. Now select the framework which is react, and here we have to select language, which is JavaScript. Let's go into that project by CD, Cartwis and hit Enter. Now write NPM install for installing all packages. Good. This folder in our VS code. So code dot. Let's close this terminal. We don't need it and also close this folder. Now, let's verify our project is working or not. So open up terminal by Control plus BT or Command plus BT and write NPM run Down. Press Control or command and click on this link, and it's working properly. Now, let's at some basic styles and layout for our project. So we have two section in our application. First one is, of course, Navbar, and second one is main section for routing. So here, let's open app component, and first of all, let's remove all code, and just simply add here boilerplate code. Now, let's define our website layout. So first of all, we will add here class name to app. Now inside this, we have for NaBr, add Nau tag and pass here Navar. Now next, we add main tag and inside this, we will perform all routing. Now let's add styles for this layout. At the top, we import period slash app dot CSS file. Save this file and open app dot css file. Let's remove all styles from here and add dot app. We want to define our application into row. So we use here display to grade and grade template rows to a pixel for first section and Auto for our main section. The changes and C, we get our layout in the middle. So let's remove default styles, which we added to our project. So open index dot CSS file, and let's remove all these tiles. We don't need it. First of all, we had star ci brackets, margin to zero padding to zero, and box sizing to border box. Now, in the body, we add font size to 16 pixel, background color two has F six, FFA. Save the changes and take a look. See, here we get our layout, but our font looks a little bit ugly. Let's quickly add font, open Google Fonts website, and we have already selected our font, which we used in previous project. Go to Import section, copy this Import CDN. In our index CSS file at the top, we paste that CDN link. Now to apply font, we copy font family and paste it in our body style. Save the changes and take a look. Now our font looks good. 104. Building Navbar Component: I now let's build our Navbar. So instead of writing all code in app component, we will create a separate component for our Navbar. So let's cut this Navbar from here and in the source folder, we create a new folder called components. Inside this folder, we create one more new folder called Navbar. And inside this, we create a new file called navbar dot JSX, and also create one more file for navbar dot CSS. Now in our component, let's say boilerplate code. And at the top, don't forget to import periods slash navbar dot css file. Now, first of all, let's at all markup for our Navbar component. So we can divide our Nabar into sections. First one is left part of our Nabar which have our website name and one input box with search button. Second part is we have multiple links. So at the place of this due, we paste our NOW tag and give it a class name to Navbar. Now inside this tag, we had two dues, one for left side, and another for right side. Now in the first du we add H one tag and pass here class name to NaBr underscore heading. And here we add our website name Cart Wish. Now, after this H one, we add one form with class name, NaBr underscore form. I will tell you later why we add here form. Now, in this form, we add one input with type text, and also we add class name to Navbar underscore search and placeholder to search products. And after that, we will add one button with type submit and give it a class name, search underscore button, and right here, search. And that's all we want to add in our first part of NaBr. We will add second part, which have links in next lesson. Save the changes and take a look. We don't get anything because we forgot to add our Nabar component in our app component. So in app component, we add here New Bar, and auto Import works. Save the changes and take a look. See here we get our elements. Now let's add styles for these elements. So in Navbar dot CSS file, we add Navbar, and in Ci brackets, first, we will set display to flag, align items to center, and justify content to space between. By these, our two parts get separated from each other. Now padding to zero and 40 pixel and background color to white. After that, we had dot Nebr underscore heading, colli brackets, margin right to 20 pixel, and font size to 32 pixel. Save this and see here we get our heading. Now we have to move this form in same line. So for that, we have to also use display flex and align items to center. So let's make separate class for these two properties because it will used a lot in our application. So cut these two lines, and in the index dot CSS file at the bottom, we add new class called Align Center and past dtiles inside this. Save this file and let's add this class first before new class and also for this first due class name to align center. Save these and back to Nabart css file. Now let's set styles for our form. Sot NebrUerScore form. And in CL brackets, we add width to 450 pixel, height to 40 pixel, Bader to one pixel, solid has CD CD CD water radius to five pixel and padding to three pixel. After that, we had dot search bar, underscore search, Cali brackets, and inside these, we add flags to one because we want our input to cover all available space in our form. So for that, we have to also add Align Center class to our form. Save this and back to our CSS file. Here we add height to 100%, padding to zero and seven pixel, one size to 20 pixel, one weight to 500, border to none and also outline to none. Save the changes and take a look. Let me zoom out to 100% and see it looks good. Now, let's add style for this search button. So we add search underscore button, Ci brackets, height 200%, padding to zero and ten pixel font size to 20 pixel, font weight to 500, Wer to none, Border radius to five pixel. Round color to has 64, 57f9. Color to white and cursor to pointer. Save the changes and take a look. See, we get our left nav bar, but here is one thing. All these inputs and button has default font family. I want to use our font for them also. So in index dot CSS file, and move this font family inside these all styles. A elements a monster at font. Say these and see now this looks good. 105. Adding Navbar Links: Now, let's say links in her NaBr. So here in the second day, we add class name to NABRUnderscore, inks. Now inside this, we want to create links. So we add ECA tag and HF to has, and inside this, we add home. And for Imog we add image tag and give it a class name to ink underscore Imog. Now let's set some images for our project. In the resources folder, we have Project three folder, and inside these we have assets. Simply select all these images and drop it into our VS code Assets folder. Now at the top, we import rocket from here we go two folders up assets slash rocket dot PNG. And let's simply pass this rocket here. Save the changes and take a look. Here we get what we want. Now, let's add style for this link. So first of all, we pass class name in this anchor tag and set to Align underscore center and also add Align underscore center before Navbar underscore links for vertically align our items. Save these and in the navbar dot css file at the bottom, we add Navbar underscore Links Cl brackets, one size to 20 pixel. After that, we add dot NabrUnderscore links, angle bracket. Here we target Anger tag, and inside this margin to 15 pixel. And at last, we ad dot Link underscore ImogKLibackets, width to 25 pixel, and margin left to five pixel. Say the changes and see here we get nice Link. Now let's set some basic styles for all anchor tags. So in index dot CSS file, we add anchor Calibackets, font size to inherit, font weight to 500. Text decoration to non, color, to inherit, and cursor to pointer. See the chinges and take a look. See, here we get our style, but I think our font size is not applied. So I inspect these and see here we don't get font size property. Probably I write wrong class name. So in the Nava component, here we can see, I have to add NBR underscore links. Sorry for this. Save this and see it looks really nice. Now you might think when we add other links, so we can create component for this individual link. So cut this link from here and in the Nabarfolder, we create a new file called ink with icon JSX also we create a new file for link with icon dot css. Now sometimes you might ask why we create every component CSS file separate. The reason is if we create separate CSS file for every component, then we can directly use that component in other projects with its CSS. Here we add our boilerplate code by RAFC and at the top, we import period slash ink with icon dot css. Good. Now at the place of this due, we paste our link. Also, let's cut this link image style from Nabar and paste it in our link with icon CSS file. Now, let's make this component reusable. So here we need three props, first link title, which is this home after that, link, which we can pass in this HF, and last, we need Imog which we use in this image tag. Let's replace the static values with our props. Link Title and Imoge. Save this file, and now in the Nebar component, we add here link with icon component, and here we pass our props. So title to home, link to forward slash and Imoge to rocket. Now let's duplicate this link five more times. And for different links, we need different Imogs. So we need to also input that at the top. Let's also duplicate this input statement five more times and we change this title to star and image to glowing star dot PNG. Next, we have ID button and image ID button. Next, we have memo and image, memo dot PNG. Next, order an image to package. And at last, we have log image to log dot PNG. Now, at the bottom, we change our second link title to products, link to slash products, and image to star. Next, title to login, Links Login and Imog to ID button. Next, we have title to sign up, link to slash signup and Imoge to memo. Next, we have title to M Orders, link to slash My Orders and Imoge to order. And at last, we have title to logout, link to slash, logout and Imoge to log. Save the changes and take a look. See, we have these beautiful links. Now we only need to add cart link, which is a little different than these links because we have to add our card count. So here we add one more car tag, HRF to slash cart and here we pass class name to line center. Now inside these, we pass our link name, which is cart. For count, we add one paragraph and class name to line center and cart underscore counts. And inside this, we pass our count number, which is zero. Save this, and let's add style for this. So in Navbar dot CSS file at the bottom, we add card underscore counts, Cl brackets, and inside it, we add justify content to center, and that's why we add align center class before card counts. After that, width to 20 pixel height to 20 pixel, order radius 200% for full circle. Background color to a 64, 57f9, color to white. One size to 15 pixel and margin left to five pixel. Seize the changes and take a look. See, here we get our counts. So you can see how beautiful this navbar looks. I know styling part is a little bit boring, but it is also necessary part of any project. So we have to do that. And as we are doing it, let's simply do that joyfully. 106. Building Hero Section: Now, let's build our hero section for landing page. This hero section is the first thing which user will see in our website. So we have to make this really nice. So first of all, here we create a new folder called home in which we will store all our components related to homepage. So create a new file called homepage dot JSX. And here we add boilerplate code by using RAFC. Did you notice how fast and simple this react becomes when we just create two applications? Imagine you work with each project with this intensity, how far you can go into web development career. It is just a matter of time. So on our homepage, we want to display first hero section, then we have feature products and then also hero section. The reason we don't create homepage dot CSS file because we don't want to add any style for our homepage. All you are part is separate components. In home folder, we create a new file called herosection dot CSS. Also, we create another file, Herosection dot JSX. Add boilerplate code here, and at the top, we import hero section, that CSS file. Good. Now, at the place of this de, we add section and give it a class name, hero underscore section. These we need two parts. First for details and second for image only. So create D with class Align underscore center times two. Good. Now in the first part, we add two with class name, hero title, and inside it, we write by iPhone 14 P. After that, we add one paragraph and give it a class name, hero underscore subtitle. And we pass here dummiteg for subtitle, so write Lorem, 15, and press tab. And after that, we add one anchor tag for By now button and give it a class name, hero underscore ink. Now in the second part, we have to add image tag, source to iPhone and give it a class name to hero underscore image. Now, let's import this image at the top. So I import iPhone from here we go two folders up assets iPhone 14 prob P. Save this, and let's add hero section component in our homepage component. Save this and also we have to add our home component in our app component. You can see how Autoiport makes our process fast. Say the changes, and here we get error. Sorry, by mistake, I add home section dot css file. So in our hero section component, we change this to hero section dot css file. Say the changes and take a look. We can't see anything because of our large image. So let's add style for our hero section. In hero section dot CSS file, first we add Hero underscore section, Gully brackets and inside it, we set display to GED, GED tempt columns to one FR and one FR for same with columns. Height to 550 pixel, padding to zero and 60 pixel for left and right. Background color to black and text color to white. Now after this, we add that hero underscore section, angle bracket. Here we target Du Culiacket and we add justify content to center, flex direction to column, and text line to center. Here we can use flexbox property because we already set Align center class for these dives. Now, after this, we add style per hero title, so dot Hero underscore title, and font size to 45 pixel, font weight to 700 and margin bottom to 15 pixel. After that, we had got Hero underscore subtitle. And inside this, we add font size to 24 pixel, margin bottom, 232 pixel and width to 70%. Now after this subtitle, we have our link, so dot Hero underscore link. And inside this, we add padding to 16 pixel and 32 pixel. Text transform to uppercase letter spacing to 1.5 pixel font weight to 700, border to two pixel, solid as FFF, border radius to 32 pixel, background color to white, and color to black. I'm going little fast for styling section because I don't want to bore you by explaining each and single style. And also, I don't want to use simple style because if our application has good functionality, but style is not good, then your project might look a little bit boring. Now, let's add O effect for this link. S dot Hero underscore Link, column O. And inside this background color to transparent and color to white. We can also add here transition to all 0.3 second is in out for smooth over effect. Now let's set style for our hero image. So dot Hero underscore image, and inside the cur brackets, add height to 500 pixel and also we want to add hover effect for this image. Transition to all 0.3 seconds is in out. After that we add that hero underscore image, column O inside this, we simply transform to scale 1.05, save the changes and take a look. See how beautiful this looks. I really like this style. Let's make this hero section component reusable. So in the hero section component, which props we want. First, we want title, then subtitle, ink for B now and image for display hero image. Now, let's replace these strings with our props. So title with title Dmitex to subtitle. And here we pass ink in HRF, and at last we have image, we replace this iPhone with image. Let's at the top, got this import from here. We don't need it in this component. Save this and in the home component, we add that import at the top. Also we import one more image Mac from two folders up assets, and here, let's see our image name. Select this Mac system, press F two and copy this name from here. I use this trick because I don't want to do mistake in importing images. So we can simply paste it here. Now let's pass our props in this hero section component. So first, title equals to by iPhone 14 P. Subtitle to experience the power of the latest iPhone 14 with our most pro camera ever. Link for now just forward slash and image to iPhone. Say the changes, and it's working the same. Now let's duplicate this hero section component and move it at the bottom. Now at the place of this title, we had build the ultimate setup. For subtitle, we add you can add studio display and color matched magic accessories to your bag after you configure your Mac Mini. Again, link to again forward slash, we will change it later and image to Mac. Here I notice I made mistake in by iPhone 14 title. I make sure about long subtitle tags during this recording, but I made mistake at the beginning. Need to work on my typing, save the inges and take a look. See, we have our both hero sections. This looks really nice. Now in the next lesson, we will create feature product section, which we will add between these two hero sections. I know this is little long lesson. You can take five to 10 minutes break and get some fresh air, and I will see you in the next lesson. 107. Adding Featured Products Section: Now, let's add featured product section for our homepage. So here in the home folder, we create a new file called featured products dot CSS, and also we create a new component called featured products dot JSX. Now you might ask why I am creating CSS file first and then JSX file. It's simply because if we create CSS file at last, then we have to switch to again JSX file. So in this JSX file, add our B Blet code, and at the top, we import our featured products to CSS file. Good. Now at the place of this de we add section with class name, featured underscore products. Now in this section, what we want. First, we want heading, so two and add here featured products. Now after this, we want to add three products card, so we have to wrap them in another De and give it a class name, featured products list. And we know this is list, so we can use here Flexbox. So before this class name, we add Aline underscore center. Now, inside this, we create one article and give it a class name, product underscore card. And for now, just pass here product. Save the changes and take a look. Sorry, we again forgot to add our featured products component in our home page. So between these two hero sections, we add our featured products component. Save the changes and take a look. See, here we get our featured products. Now let's set styles for them. In featured products dot CSS file, first, we add featured underscore products, cool brackets, margin to 65 pixel. After that, we add featured underscore products, angle bracket, and here we target two tag, which is our heading. And right here, one size to 48 pixel, text align to center, and margin bottom to 65 pixel. At last, let's set style for our product list. So dot featured underscore products, underscore list, coli brackets, and add here, justify content to space between. That's why we add Align Center class for this list. And after that, we add Margin, bottom to again 65 pixel. I am again telling you I can write this CSS because I practice a lot for this project. If I create this project first time, then I have to also do trial and error thing for these tiles. I practice it because I don't want to waste your precious time for trial and error of simple styling. See the changes and take a look. See, we get our feature product section. Now in the next lesson, we will create product card for this project. 108. Creating Product Card: Now, let's create product card component so we can use it multiple times. So here, let's cut this article tag we create a new file called product card dot CSS. And after that, we create a new component called product card dot JSX. Let's add boilerplate here, and at the top, we import product card CSS file. Good. Now, at the place of this de, we paste our article tag which we just cut. In the product card, what we want? We want to DUs. One for display, the product poster or image, and second, for product details. So here we add Du and give it a class name, product underscore image. And inside this Du, we add our image tag and give it a source, let's say, iPhone and art to product image. Let's import this image at the top. So embodiPoneF here we go two folders up assets slash pon dot JPG. Now, here's one thing. I want to redirect user to selected product page in which user can see other details about that product. So we can wrap this image with anchor tag. You want to know how I'm doing this, let me show you it's really simple. First, select the tag you want to wrap and press Control plus Sift plus P or Command plus Sift plus P W here, wrap with abbreviation, select this and right here tag name and hit Enter. See, we get this. Now in HRF, we can pass like this product s one. This one is product ID. Now after this DU, we add one more du with class name, product underscored details. Inside these, first, we add H three tag and give it a class name, product underscore price. And here we write dollar 999. After that, we create one more paragraph and give it a class name, product underscore title. And right here, iPhone 14 Pro. Now at last, we have one line, which have two sections. First one has rating and rating counts, and another has to cart button. So we create one Potter tag, and give it a class name, a line center, and product info footer. Now inside this, we add one DU and give it a class name, a line center. Now inside this d, we need two paragraph, one for rating and one for rating count. Add first paragraph and class name to align center and product rating. You can see how Align center class is more useful in terms of centering things. Now inside this, we add image and in source star and art to star also. Here we write our rating, 5.0. Now after this paragraph and give it a class name, product, underscore review, underscore count. And right here, 120. And at last, after this dive, we add here button and give it a class name, add to cart. And inside this, we add image, and in source, we pass basket and RT to basket. Now, let's input these two images at the top. So duplicate this input two more times, and here we write star and image name to white dstar dot png. And for last, we change it to basket and image to basket dot PNG. Save the changes. And in the features products component, we add product card component. Nice. And now let's duplicate these three more times. Save this and see, we messed up our landing page. Let's set style for this. So in product card dot CSS pile, first of all, we add dot product underscore card. El brackets and inside this width to 275 pixel height to 330 pixel, margin to 20 pixel, wer radius to 12 pixel, box SDO to RGBA, zero, zero, zero, 0.24. And after that, zero pixel for XX, three pixel for Y axis, and eight pixel for blur effect. If you want to explore other box shadows, then I have one website which I used a lot when I want to add box shadows. So in the new tab, search, get CSS scan. And here we get 93 beautiful box shadows. And we can copy it CSS directly clicking on that box. So you can bookmark this website. Back to our CSS file. Here we add background color to white. Now, after this, we add dot product underscore image, and inside the Cali brackets, we add height to 200 pixel, text align to center, and border bottom to one pixel, solid has if if I Ii. And after this, we target dot product, underscore image, and image tag. And inside this height to 100%. Save the changes and take a look. See, our image section is ready. Now let's set style for this detail section. So we add here dot product, underscore details. And inside this, we add padding to ten pixel for top bottom and 20 pixel for left and right. After this, we target dot product, underscore price, Calibacket and inside this, we add font size to 21 pixel and font weight to bold. Now let's add style for dot product, underscore title. And here we add one size to 18 pixel and margin top to four pixel. Save this, and still our card looks mass because of this image. So let's fix this. So here we add dot product, underscore info, underscore footer. Ali brackets, and here we add justify content to space between and margin to ten pixel for top bottom and zero for left and right. After this, we target dot product underscore rating, Cali brackets, height to 30 pixel, padding to four pixel and eight pixel font weight to 600. Border radius to five pixel, background color, to a FC a 311, and color to white. After this, we target dot product, underscore rating, image, coli brackets, and inside these with to 20 pixel and margin right to five pixel. After that, we add dot product, underscore review, underscore count, Cali brackets, and inside this font size to 16 pixel, margin left to ten pixel, color to gray, padding to zero and ten pixel, and water left to two pixel, solid has DC DC DC. Save this and take a look. Here, we can see our style because of this basket image. So cts code, and here we target dot at two CAT Coli brackets, and inside this with 40 pixel, height to 40 pixel, border to nun, border radius to 100%, background color to transparent. And cursor to pointer. And at last, we target dot A to card and image tag Cully brackets and width to 100% and height to 100%. Say the changes and take a look. See, now our card looks really good. For now, we are not making this product card component dynamic because we will get this data from our back end in upcoming section. So our lending page is ready now. 109. Building Product Page: So in the previous lesson, we complete our home page. Now let's start our second page, which is product page. So we can divide this product page into sections. First section is sidebar in which we display all our categories, and on the right side, we have list of products. So I close all files from here. And now in our components folder, we create a new folder called products. And inside this, we create a new file called Productspage dot css. And after that, create a new component called products page dot JSX. Now, let's at boilerplate code using RFC and at the top, we input period products page dot CSS. Now at the place of this dew, we add section and give it a class name, products, underscore page. And inside this section, we have two things sidebar and list of products. So let's add here a side tag and give it a class name, products, underscore side bar. And inside this, we write side bar. After this sidebar, we create one more section and class name two products, underscore list, underscore section. And right here, product list. Let's see what we get. Save this file, and in the app component, we comment out this homepage and add here products page. And here we can see I add product page which is different from CSS file. So we change this file name to products page dot Jx. Also, in that component, we change our function name to products page, and also update this export. And at the top, we add products page dot css. Save this file, and in our app component, we add here products page component. Don't worry. We will add routing after completing our styles. For now, we don't want any complexity. Save the changes and take a look. Here we get sidebar and products list. Let's set style for our products page layout. In products page dot CSS file, we add dot products, underscore page, Calibrackets, display to GED because we want to divide our application into sections, GED template columns to one frame and four frame and padding to 20 pixel. Save the changes and take a look. See, we get separate sections. Now, let's add our side bar. So instead of writing whole sidebar section here, we can create a new separate component for sidebar. So cut this aside tag, and in products folder, we create a new file, products, sidebar dot CSS, and create another file Products, sidebar dot JSX. Here we add boilerplate and let's import period slash products sidebar dot css file. Good. Now at the place of this DU, we paste our AI tag. Now, let's remove this sidebar text, and inside this, first, we add Astro tag and pass here category. After that, for displaying the links, we create one DU with class name category underscore links. And inside these, we will add our links per category. So let's add styles for this part. So in our CSS file, we add dot products, underscore sidebar, Hi brackets. And inside these, we add padding to ten pixel for top bottom and 20 pixel for left and right, border radius to five pixel and background color to white. After that, we will add style for category heading. So dot products underscore sidebar, and we target two Cali brackets, font size to 26 pixel and margin bottom to ten pixel. Save this. And in the products page component, let's add our products side bar component. Save this file and see, here we get nice side bar. Now let's set category links. So category links look like this. On left side, we have Imog or icon, and then in the right side, we have link title, where we see this type of structure, right, it is linked with icon component. Difference is just this. We have to change their positions, which we can easily do with CSS. Let me show you. So here we add link with icon component, C, auto input works, and at props, we pass title to let's say electronics after that link to products, question mark category equals to electronics. So here we are passing our category inquiry string, and by using that, we can fetch data from that category. After that image, let's say rocket. Now let's import this image. Import rocket from here we go two folders up assets rocket dot png. Save the changes and take a look. We get the same link as we are getting in our nav bar. Now, how this link with icon component knows, we want to add this link to side bar or Na bar. For that, we will pass one more props to this link with icon component. Side bar equals to true. Or we can also remove this. This both works the same. But for better understanding, we are not removing this. Save this and head over to link with icon component. Here, after this image, we destructure one more props, which is side bar. Now here we can add condition, and based on that condition, we will add styles. So at the place of this Align center class, we add cli brackets because we are adding JavaScript expression and add here condition I sidebar is true, then we return Align center, and sidebar underscore link as we only return Align center. Now let's set style for this sidebar underscore link. So on link with icon dot Css file, and at the bottom, we add sidebar underscore ink, Calibraket and inside this, first, we need to change the position of our image and text. So flex direction too reverse justify content to flax and by using these two properties, we can reverse the position of our elements. After that, one size to 21 pixel, padding to ten pixel and 15 pixel, border radius to five pixel and transition to all 0.15 second is in and out. You already know why we add this transition, pH effect. Sidebar Link clan hover and inside this, we simply change background color to as F six, F six, F six. Save this and take a look. See, we get our link style. Now let's make our icon little big and add margin right. So here we add dot sidebar underscore Link, and we target image element. Inside this, we change width to 30 pixel, margin left to zero, and margin right to eight pixel. The reason why we make margin left to zero is because in this link underscore Imoge we have margin left to five pixel. Save the changes and take a look. See, here we get our link style. So this is how we can use the same component and use it for another style. 110. Creating Product List Section: Now, let's create product list section for our product page. So A for this section, we create a separate component. So at this section from here, and in our products folder, we create a new file, products list dot CSS, and also we create a new component products list dot JSX, add boilerplate, and at the top, we import product list dot CSS file. Now at the place of this due, what we will do, we paste our section. Now, this product list section has two sections. First one is header, and in that, we will add title of product, and on right side, we will add dropdown menu for shorting our products. In the second section, we have list of products. Let's add here header with class name, Align center, and products, underscore list, underscore header. Inside this header, first we add to tag and inside these products. And after that, we add select tag name to short and give it a class name, product, underscore sorting. Now inside this, we add our options. So option, value to null and pass here relevance. This is the default value, and that's why we pass no value. Let's add second option value to price, DSE for what, right, for descending, and pass here, price high to low. Duplicate this line, and we change our value to price, ASC and change here, price, low to high. Now, let's duplicate these two options and at the place of price, we change to rate and here also rate. Now, after this header, we add one day with class name products underscore list. And inside this, we have list of products which we will display in product card. So instead of defining product card component in home folder, we can move them to here in the products folder. So see like this, both file and drop it into products folder. You can see how easy to move components in our project, or we can even use it in different projects with its CSS file. But here is one thing. We have to change the input statement in feature products component. So here we go one folder up products, slash product card. Save this. And in the product list component, we add here product card. And duplicate it a couple of times. Save this file. And in our products page, we add this product list component. Don't forget to do that. Save the changes and take a look. See, we get these elements. Now let's add style for this section. So I product list dot CSS file, we add dot products, underscore list, underscore section, Cali brackets, padding to ten pixel and padding left to 30 pixel. After that, we add dot products, underscoe last, underscore header. And inside these, we add justify content to space between because we already had aligned center class for this header. After that, we target our two sudar products, list header two Cali brackets. And here we write font size to 26 pixel. After that, we target to our products underscore shorting, Calibackets, and inside this font size to 18 pixel font weight to 500, font family to inherit height to 35 pixel, padding to zero and five pixel for left and right. Border to nun, outline to nun, and border radius to five pixel. Save the changes and see our header section is ready. Now we have to just add style for this products list. So at the bottom, we add to products underscore list. And inside the Scully brackets, we add display flags flax wrap to wrap and justify content to space evenly. Save the changes and take a look. See, our product list is ready. So congratulations. We completed our two important pages. This looks really good. What do you think? Let me know in Q&S section. 111. Creating Single Product Component: I now let's create single product page for our project. In this lesson, we only create the image selection part. So here we have array of images, and when we select any image that image will display here. It is really simple. Let me show you. So first of all, in the next article 0R in the resources folder, open projectory folder. And in this, we have products dot JS file. And inside this, you get this product object. This object has all details which we will get from back end. For now, we just need this Dummi data. So for single product section, we create a new folder in components folder called single product. Inside this, we create a new file called single product page dot CSS. And also we create a new component called single product page dot Jx. Here we add boilerplate code, and at the top, we import single product page dot CSS file. Good. Let's add our product object here because we need it. Now at the place of this DU we add section and give it a class name, a line, center, and single product. Inside this, we have two sections, one for image selection and second for display the product details. We add here Du with class name, align, center, and second, Du with class name, align, center, single product details. Now in this images du, we add one more du with class name, single underscore thumbnails. And inside this, we will display all images thumbnail, which means small images. Which images we want to display. Right, we want to display these images array. So add Coli brackets, product dotimages dot Map. Inside this, we get each image and also index here. This is very basic, right? We have done this so many times, and here we return image tag. And in the source, we pass our image Alt to product dot title. Now, after this due, we add one image source to product dot image. And inside this, we have to pass zero for now. Alt to product, dot title and class name to single underscore product, underscore display. Save the changes, and we have to add this page in our app component. Circumn our product page and simply add here single product page. Save the genes and take a look. We get our elements. Now let's set style for this section. So in single product page dot CSS file, first we add single underscore product, calibraket and here we add justify content to center and padding to 32 pixel for top bottom and 48 pixel for left and right. Next, we target to single underscore product, underscored thumbnails, coli brackets, and inside this display to flag flax direction to column, flax wrap to wrap, gap to 14 pixel, padding to eight pixel and margin to 16 pixel. After that, let's target those small images which we can select. So that single underscore product, underscore thumbnails, image Calibackets width to 80 pill, height to 80 pill, object fit to cover water radius to five pixel and cursor to pointer. After this, let's add dot single underscore product, underscore display, Calibrackets, and inside the width to 600 pixel, height to also 600 pixel, object fight to cover and water radius to ten pixel. These are all basic CSS. That's why I'm not explaining its style. Save the changes and take a look. See, we get what we want. When we click on these images, nothing happens. So let's set this functionality. So for that, we have to create one state variable called selected image set selected image, and this state variable will store the selected image index value. By default, we will select first image. Let's also import state from react. Good. Now in the bottom at the place of the zero, we add selected image. Now when we click on any of these images, we just have to set our selected image value to that index value. Let me show you. Here, we add on click event in this thmalimage arrow function, and set select image to index. Save the changes and take a look. Change the image and see, we get that image here. Now we just need to display which image is currently selected. So in our image tag, we add here, class name equals to here we pass condition. If selected image equals to index, then we add selected underscore image class, else we add nothing. This and let's add style for this class. So in the CSS file, after our image style, we add dot selected image Coli brackets, transform to scale 1.12. Save the changes and see, here we get this selected image. Now, this effect is very sudden. So let's make this smooth. In this image style, we had transition to all 0.2 second, es in out, save the changes and take a look. See, we get this smooth transition effect. You can see how image selector feature is very simple. Just we to think in simple way. Now in the next lesson, we will add product detail section for this page. 112. Adding Details Section for Product Page: Now, let's add details section for single product page. In this details, we add H one tag with class name, single product, title, and inside this, we will display product dot title. After that, we add one paragraph with class name, single product description. And inside this, we add product dot description. This is the benefit of product object. After that, we add one more paragraph tag and give it a class name, single product price, and add here dollar curly brackets, product dot price, dot two fixed, and inside this, we pass two. This will round off our price to two digits. Now, after this, we add two tag with class name quantity title and pass here quantity. After this, we add one die with class name, align, center, and quantity input. And inside this du, we add button with class name equals to quantity input, button, and pass here minus, and by default, we add disable to true for minus button. Duplicate this button, remove this disable. And just pass here plus. And between these both buttons, we add paragraph with class name, quantity input, count. Good. Now at last, we have head to cart button. So we add button with class name, Serge, button, and add cart. And here we pass head to cart. Save the changes and take a look. See, here we get all our elements. Now, let's set styles for them. So in our CSS file at the bottom, we add single product details, Cali brackets with 35% and padding to 16 pixel and 24 pixel. After that, we have single product title. And here we write margin bottom to 16 pixel and font size to 32 pixel. After our title, we have description. So that single product description, c brackets, and here we add margin bottom, 16 pixel, and line height to 1.4. After that, we have price, so dot single product price. And inside these scaly brackets, we add margin bottom to 16 pixel, font size to 24 pixel, and font weight to 600. After that, we have quantity title. So quantity title. Font size to 20 pixel and font weight to 700. Save the changes and take a look. First, we need to make our details in column. So our single product component here in our details do, we bimestaally add a line center. We don't want that. Save the changes and see, now we have little good structure. Let's add rest of the styles. Back to our CSS file. After these, we have dot quantity input, du and inside this, we set font size to 20 pixel, font weight to 700 and margin to five pixel for top, zero for left and right, and 16 pixel for bottom. After that, we target dot quantity input button, Calibrackets, and inside this, we add width to 35 pixel, height to 35 pixel, for size to 25 pixel, background color has FF 8848, color to white, border, nun, wer radius to 100%, for circle and cursor to pointer. Now let's set style for disabled button. Quantity input button, Callan disabled, and inside this we add opacity to 0.3 and cursor to default. Save this and see we get our button styles. Now we only have to add style for this count and add to card button. So we add here quantity input, count, Cali brackets, margin to zero, and 40 pixel for left and right, and text line to center. And finally, at last, we target dot eight card button, Cali brackets, and inside this with to fit content and padding to eight pixel for top and bottom and 18 pixel for left and right. Say the changes and take a look. Rest of the styles are okay, but here we need to do one little change. We add here margin bottom, and also let's see why we don't get margin for this quantity input die. So in our quantity title style, we add margin bottom to three pixel, and here we remove this die. We want to apply this style for quantity input. Save the changes and take a look. See how beautiful our single product page looks. The reason why I recommend to write style by your own is because after completing this project, you will proudly say that I create this project from scratch. One more thing, if we remove CSS part from front end development, then react will lose its value tremendously. Without right CSS, our website looks very ugly. Give yourself credit for creating this project from scratch. 113. Building Cart Page Component: Now, let's create cart page for this project. So in this lesson, we will create all things without this table. We will create a table in the next lesson. So in the components folder, we create a new folder called CAT and inside this, we create a new file called Cardpage dot CSS. And after that, we will create one more component called Cardpaget JSX. Here boilerplate, and at the top, we import card page dot CSS file. Now at the place of this DU we add section and give it a class name, line, center, and cart page. Inside this section, first, we want to create user info. So we can create that element here or we can separate that component. We can do whatever we want to. It totally depends on us. Here we are not going to reuse this user info, so I'm not creating component for that. Dot Align Center for adding another class in T, we can add another dot user Info. See, we get this both class. Now inside this, we first want to add user profile image. Image tag and source to user Alt to user profile. Now after this image, we want one Du and inside this Du we add one paragraph with class name, user name. And we can pass your name to Halley. And after that, we create another paragraph with class name, user email, and pass your email to Halley at dire gmail.com. Save this and in the app component, we need to add this card page. Comment out the single product page, and after that, we add card page component. Save the changes, and we get nothing. So open up Console and at last, we can see caught reference error, user is not defined, and also we get a file name, card page, and also number of line. So back to VS code, and let's import this user. So import user from we go to folders up assets, user dot web P. Save the changes and take a look. See, we get user Info. Now, let's add other elements. So here we give space for card table. After that, we add table for cart bill. Table and give it a class name, cart underscore bill. Here we add Tbody and inside it, we add table row and table data. Here we pass subtotal and another data dollar t nine. Let's duplicate this table row two more times, and at the place of this subtotal, we add shipping charge, and here dollar five. After that, for last row, we add final total and at last dollar 1004. Now after this table, we add button with class name, search button, which we define in Navbar, and also we add one more class, Checkout button. And here we pass checkout. Save the changes, and take a look. Here we get our elements. Now let's set styles for them. So in cart page dot CSS file, we first add dot cart page Cali Brackets and inside this, we add flex direction to column, justify content to center width to 60% margin to zero and auto and badding to 32 pixel and 48 pixel. After that, we add data user info, and in Gali brackets, gap to 16 pixel and margin bottom to 32 pixel. After that, we target data user underscore info, image, and inside this, we add width to 80 pill height to 80 pic L, object feet to cover and border radius to 100% for a circle. Now after that, we target dot user underscore name. And in Cully packets, we add font size to 21 pixel font weight to 600, Save the anges and take a look. See, we have nice user info. Now let's set styles for this table and button. So at the bottom, we add dot cart Bill early brackets, and inside the align self to flex and with to 400 pixel, water collapse to collapse, one size to 16 pixel, margin top to 16 pixel and background color to white. Next, we add dot cart, Bill, TD, Ci brackets. And inside this, we pass padding to 12 pixel and 20 pixel and border to three pixel, solid has EI EI, ei. After that, we add dot cart, Bill, TD, call on last child, Cali brackets, and inside it text line to and width to 120 pixel. After that, we target dot Cart, Bill, final, and inside this font size to 20 pixel and font weight to 700. And finally, at last, we target Checkout button, Ci brackets. First we add align self to flex because we want to display that button at right side. And also, we add that for cart Bill. S? After that, height to 38 pixel important margin to 16 pixel for top bottom and zero for left and right, and padding to zero and 16 pixel for left and right. Also add important here. Saves and take a look. This looks nice, but our final styles is not applied. So back to cart page component. Here we add class name to card Bill final. Saves and ta a look. See, these styles looks really good. Now in the next lesson, we will create card table. 114. Creating Common Table Component: Let's create common table component. You might think, why we need that. Let me show you. Here in the card table, we have one particular table style and the same style we have on the My Order page. The difference is just a data. Here we have different data with different heading. You can create common table component and use it in both pages. At the place of this card table, we call table component like this. And for heading, we pass here props, headings equals to in curly brackets, array, and inside this, we pass all headings which we want to display. So first, we pass item price quantity, total, and remove. Now, let's define this table component. I know this is a little confusing for now, but just see this and you will understand that. So in components folder, we create a new folder called common and inside this folder, we will add all our common components. Now, let's create a new file called table dot css. And after that, we create a new component called tablet JSX. Let's add boilerplate code and at the top, we import table dot css file. Now, at the place of this de, we add table tag and give it a class name common table. Now, inside this, we add THAD and inside it, we add tableow for heading. Now, as we know, we are going to use heading props, which is array. So we destructure props and get here headings and inside this TAD, we can render our headings. So headings dot MAP inside this, we get each item and also index arrow function, and here we return Ts tag, key to index, and just pass here item. For now, let's see what we get. Save this. In the cart page, we have to import this table component from common component folder. Save this and see, we get this table with headings. Now for displaying data, we can pass here another props, but we are going to use another method. Sometimes we need to pass JSX as props. For example, here we want to pass T body tag with the list of items, which is our JSX. So we want to pass this JSX in this stable component. How can we do that? It is really simple. Instead of passing JSX in props, we can add that in children. Let me show you what I mean. So here, instead of self closing this stable component, we can use this component as our STML tag. And between the opening and closing component, we add our JS so here we at T body and inside this, we at table row and inside it, we have table data. IPhone six, duplicate this four more times because we have five headings. Here we at price, dollar 999, quantity to one, total to dollar 999, and at the end, we add remove. Save this and take a look. We don't get our data because we don't define where we want to show that children JSX. So one table component, and in the props, we have one property called children. This children has all JSX, which we pass between our opening and closing component. Now let's add this component simply here. Save the ings and take a look. See, here we get our data. So our component is working. Let's set styles for this common table. So in dot CSS file, first of all, we add Common Underscore table, curly brackets, and inside this, we add width to 100% margin bottom to 16 pixel, border collapse, to collapse, background color to white. And box shadow to zero pixel, three pixel, eight pixel, RGBA, zero, zero, zero, and opacity to 0.24. After that, we add dot common table, T head, and TR C brackets, and inside these, we pass height to 50 pixel, background color, two has 36, 34 A, color to white and text transform to upper c after that, we target.com table, T body, TR, Cali brackets, height to 50 xl, and Textaine to center. And for even table row, we want to change the background color, so our table looks like this. So dot common table, T body, TR, column, Nth child. And here we pass Evan. C brackets, background color, two as FI, FI FI. Say the changes and take a look. Why we don't get style for this T head? Let's inspect this, and we can see here we are not getting style for this T head. Back to VS code. And in common table Thad. Let me check the spelling. Yes, it is true. Oh, here we need to target TH, save the inges and take a look. See, our table looks very nice. 115. Modifying Cart Page Component: Now, before we start creating our last page, let's apply some changes in our cart page. Here at the place of this quantity, we want to display quantity with plus and minus button. We already created that in our single product page. We can simply use that here. In the single product component, we need this. Instead of copy and pasting these elements, let's create a usable component for that. Cut the and in the single product folder, we create a new file called quantity input dot CSS. Also, we create a new component, quantity input dot JSX. Let's add boilerplate code, and at the top, we import quantity input dot CSS file. Now at the place of this due, we simply return our elements. You can see it gives us compilation error. So we wrap these elements with the react fragments. Good. Save this, and let's also separate CSS for these elements. Before that, in single products component, we add our quantity input component, save this, and in the single product CSS file, at the bottom, we cut these three styles, save it, and in the quantity input CSS file, we paste this. Now in the card page at the place of this one, we add quantity input component. Save the changes and take a look. See, we get our quantity controls without writing any CSS or STML code. That's the beauty of creating components. Now let's fix this style issue. So here we add class name, Align center, and quantity input. Save the changes, and in cat page dot CSS file at the bottom, we add table quantity input, CL brackets, and inside this height to 50 pixel and justify content to center. We the changes and take a look. See, we get our styles. Now, one more change at the place of this remove text, we want to display, remove icon. So go to CAT page component, and at the place of this remove text, we add image and source to remove and art to remove icon and adhere class name to CAT remove icon. Let's import this remove icon at the top. So import, remove from here we go to folders up assets and remove dot PNG. Save this and let's add style for this icon. In cart page dot CSS file, we add dot cart remove icon calibrates width to 35 pixel, height to 35 pixel and cursor to pointer. Save the ging es and take a look. See? Our paste looks really good. 116. Section 11 Advance Form: Welcome to the 11th section of the ultimate react course. In this section, we are going to learn all things about form like building the form, managing the form without any library, and also with the react hook form library. We will see both ways. After that, we will see form validation using one of the most trending library called ZOD also how we can handle file or image input in react. So let's dive into this. 117. Building Login Form: First of all, let's build our login form UI. So after that, we can learn without worrying about its design. So here we create one more folder called authentication. And in that folder, we will create our log in Form page. So we create a new file called Login page dot CSS. And also, we create a new component called Login page dot JSX. Here we add boilerplate code, and at the top, we import Login page dot CSS file. Good. Now, at the place of this day, we add section with class name, Align center, and Form page. Now inside this section, we add Form tag and give it a class name, authentication form. Now, let's add here our heading to login form. And after that, we have Du which has all input fills and give it a class name, form inputs. Now inside this for now, we are adding name and phone number, but don't worry we will change that soon. So for individual input, we add one DU and inside this, we pass label and pass your name. Don't pass anything in this DML for at reviewed. I will explain to you in just a minute. After that, we simply add input box with type text and give it a class name, form, text input, and placeholder to enter your name. Now, duplicate this do and at the place of this name, we write phone number, and here, input type to phone number, and placeholder to enter your phone number. And at last, we add button with type submit and give it a class name, search button, and form submit, and pass here, submit. Save this, and now we have to add this form in our app component. So comment out this M order page and add here Login page. Save the changes and take a look. See, we get here form elements. Now we just need to add styles for them. So in the login page dot CSS file, first of all, we will center our section, so dot FOM Page Cali Brackets, justify content to center. After this, we add Authentication form Coli brackets, and here width to 30%, padding to 32 pixel for top bottom and 48 pixel for left and right, margin top to 32 pixel and background color to white. After this, we target our form title. So that authentication, form H two, and inside curly brackets, we add font size to 40 pixel, margin bottom to 30 pixel, and text align to center. Save this and see our page title is looking nice. Now we just need to add style for this label, input fills and submit button. But before that, let's set this label and inputs in column. So here we add dot form inputs, D, and inside this display two flax, flax direction to column, and margin bottom 220 pixel. After that, we add.com underscore inputs, label, Cali brackets, and here we add font size to 18 pixel, font weight to 600 and margin bottom to three pixel. Now let's target our input fills, so dot form, text input, Cali brackets, and inside this height to 35 pixel, padding to zero and eight pixel for left and right. Font size to 17 pixel, font weight to 500, and outline to none. At last, we add.com, submit Calibraket height to 40 pixel width to 100%, and margin to 25 pixel for top, zero for left and right, and ten pixel for bottom. Save the changes and take a look. Our form is ready. Now you might ask why I left this label empty. Many developers don't really know what this estim four attribute does. Even I just learned this in my fourth or fifth project when I get started. This four attribute specify for which form element that label is bound. Let me explain to you this practically. For now, if we click on this name label, we can't see any effect. Now, here in our input field we add ID attribute and pass here name. Now in these labels estim for attribute, we have to add the same ID which we add in our input. So we write here name. Same we do with this phone number, ID to phone and tM for attribute to phone. Save the ins and take a look. See if we click on this label, we get our cursor in that input fill. That's how we use label for attribute, which specify which form element our label is bound. 118. Understanding useRef hook: Now let's see another important hook in react, which is use RF Fok. So first of all, what is use Rf hook and why it's important? Use Rf is a hook for accessing dom elements and also for creating multiple variable, which will not re render the component. These are two most common use cases for use Rf Fok. For now, let's not worry about creating a mutable variable. First, let's understand how we can access dom elements. So here in our login form, we temporarily set the phone numbers input type to password. Now, as we know, many website has this feature in which we can hide and show the input password. After this input, we add one button, we type button because if we don't specify the type attribute, then by default, it's set to submit and we have already submit button. So here we pass height password and duplicate this button and change this to show password. Say the changes and take a look. See, here we can type our password which currently not visible. Now what we want to do is when we click on this so password button, we want to set our input type to simple text. And when we click on Height button, then we will set type to password again. So for that, we need to access this input field. Now let's see how we can do that using use Rf hook. So first of all, in our component, we write us ref Hook and select this auto suggestion. Now in this, we have to pass the default value, same as we do in use date hook. Commonly, we always add here null. Now this use ref hook returns an object with only one property called current. Let's do that in variable called password ref. Now which element we want to access? Right, it's our password input fill. So in that element, we have to add one attribute called Rf. And here we pass our reference name, which is password Rf. Now let's see what we get in this password Rf. So for now, in this Hide button, we add on click event, and here we add arrow function and console dot log, password ref dot current. Save the changes and take a look. Open Console and click on Hide button. See, here we get this input with ID Phone. Now with this element, we can do anything which we do with Dom elements in Vanilla JavaScript. Now you might ask, how can we know which methods we can use with elements and also how we can remember it. So the answer is, you don't have to remember any method. Let me show you my trick to see all the methods which we can use with elements. So here, simply remove this current property. And save it. Now in Console, you can see this password ref object with current property. Now click on this little arrow and again, click on this arrow. So here we can see all methods which we can apply on this element. For example, we want to apply style. Scroll down to the bottom and click on this icon to see more properly. And here you can see style property. Click on it, and you can see all styles property. Simple as that. So in our example, here we want to change the type attribute for this input. So at the place of this console dot log, we write password ref dot current dot type equals to and codes password. We just copy this onclick event and paste it for this so button. And here we just change type to text. Save changes and take a look, type something in this input. By default, it's on Hide. Now click on Show and here we can see our password. Again, click on Hide and it's Hide. And see how easily we can access dom elements using use Rf Hook. Just for a cap, we have to first declare one variable with use Rf Hook and pass here our default value, which is null. And after this, simply pass RF attribute to any element which we want to access and pass our use Rf variable name. Simple as that, if we use Vanilla JavaScript, then we have to write here document dot Get element by ID or name. But in react, we don't need to do that. We have use Rf ok for accessing the element. 119. Handling Form using Ref hook: So in the first project, we see how we can handle form using use date hook. Now, let's see how we can handle form using use Rf hook. It's really simple. Let me show you. So let's remove these both buttons. We don't need it and also remove this f attribute. I just add them for explaining use RF hook. Change this type to number and also remove this p attribute. Now here we call use Rf and pass here null for default value and give it a name, call name ref. Now in this name ref, we want to get reference of this name input. So in the input, we add ref attribute, and here we pass name ref. Now let's handle submit for this form. So here we add our on submit event and pass here, handle submit function. Now, let's define this function. We did that previously, right now in this function, for now, we simply console dot log this nameRv dot current. And in this, we have to access this input value, save the changes, and take a look, enter here name, and click consubmit. See, our page get refreshed. Why does it happen? Do you know? Right. It's because we don't add prevent default function. You can see now you know many little details about react. You are doing really great. So here we add event object, and inside this, we add e dot prevent default function. Save the changes and take a look. Open up Console, write here name, and see, we get this name here. Now, let's do the same for this phone number filled. So here we create a new ref constant, pass here null and give it a name, phone ref. You can use whatever you want to. It's totally up to you. Now in this phone number input, we add f attribute and pass here our phone ref. And in our handle submit function, let's console dot log this phone rev dot current dot VLU. Say the ins and take a look. Fill these inputs and submit it. See here we get these values. Now in the real world, we will send object of our data to server. So here we create one object called user, and inside this, we add name property and give these to empty string. And here we have phone and as default value, we add zero. Now at the place of this console, we set user dot name equals to name rev dot current value. And after that, user dot phone equals to phone ref dot current dot value. Now at last consult dot log this user object. Save the changes and take a look, fill the form, and here we get our user object, which we can send to server. One little change, we need to convert this number string to only number. So here we wp this value with parenthesis and add here parse int. Save changes, submit a form. See here we get here number. That's how we can handle form values using use Rf. Now you might ask, what is the best way for handling form? Use Rf or use state. The answer is use state. But use Rf also useful if we have up to ten input fills because when we use sref, that will not cause render the component. If we have five to six form fills, then we can simply use UtateHok. Only use sref hook for handling form. I state is causing performance issue, use userefHuk for accessing elements. In the next lesson, we will handle our form with us State hook. 120. Handling Form using State hook: So first of all, let's remove these constants, remove these lines from handle submit and also remove these f attributes from both inputs. Now, first of all, we create one state variable using SNIPID and give it a name user, set user, and a default value, we pass object with property name to empty string, and phone also empty string. Now at the top, instead of importing UF, we import Tate Hook. Now in our name input filled, we add change event, and inside this, here we get event object, arrow function, and set user to object. First, we get all values from previous user object and just replace name to e dot target dot value. Now for Fon input, we do the same. So copy this change and paste it into this input. And simply change this name to phone. Previously, we create separate function for handle change, but we can also do this way. You can use whatever you want to. It's totally up to you. Now, at last in handle submit function, we at console dot log this user object. Save the changes and take a look, fill the form and submit. See, here we get our user object. Also, we need to convert this phone number to integer. So wrap this value with parenthesis and what we use, right, parse int. Now here we have also little problem. We know that all input fields in SDML have a value property for maintaining its own state. But with this implementation, we also have user state variable. So it's possible that the property and inputs get out of sync. It will not occur many times, but prevention is better than cure. So to solve this problem, addhe value property and set to user dot name, and also here value to user dot phone. So here we can call this input field as a control component because its state is entirely controlled by react. This simply means the value of this input is not managed by the dome, but it's controlled by component state. 121. Managing form with React Hook Form: Now, here we have only two input fills. Tomorrow, if our form gets more complex, then managing the form with used will get more difficult and time consuming because for every input field, we have to set properties like value and onchange event. In this situation, we can use one of the most popular library, which is react hook form. This library will help us to build quick forms, and we don't need to worry about managing form state. This library does that automatically in very last code. So open up terminal and in the new terminal, write NPM, I react, hook form at 7.43 0.9 and hit enter. Now, minimize this terminal. Now at the top of our component, we have to import one hook called use form from react hook form library. Now, in our functional component, we call that use form hook. This use form returns a form object. So we store that in variable called form, and after this, simply consol or log this form to see what we are getting in this form object. Save the changes and take a look. See, here we get many properties and methods like handle submit, register, reset, reset fills, and so on. So here we can destructure our form. And first of all, we need register method. This register method takes the fill name as argument and returns a couple of properties. Let me show you what I mean. So here at the place of this form, we add register function and pass here fill name. Let's say name. Save the changes and take a look. See here we get this object with couple of fill like name on blur on change and F attribute. So essentially, this react hook form will use f hook for handling the form. So as I told you, we have to use this react hook form for complex form. And when we have complex form, we use f hook. So at the place of this on change and value attributes, we can add calibracets, and here we call this register function. And pass here our input fill name, which is name. Now, as we just see this function returns a couple of properties. So to add that here, we can use spread operator. Same we do in this input fill, remove these properties and add here register function and pass here our fill name, which is phone and simply spread this. So now we don't need this state variable and also remove this handle submit function. Now here in our use Form hook, we get one more method called handle submit. This handle submit function is used to handle form submission. So here we call this handle submit function in on submit event. And as an argument, we have to pass one callback function. And in that function, we receive our form data. So here we get form data and we simply const dot log this form data. So when we submit the form, this arrow function will run simple as that. Save the changes and take a look. Fill the form. And click on submit and see here we get our data, and we don't need to write much code. Now here we are getting this phone number as a string. So for that, we have to pass second argument in this register function. So object and we set value as number to true, save the changes and take a refresh the page, fill the form, and here we get our number. So it's working. In real world application, we don't want to simply consult or log this data on submit, but we will call API or many more things. So instead of defining this logic here, we can separately define this function. So cut this arrow function, and here we create a new function called on submit and simply paste our arrow function here and pass this on submit here. You can see now our form looks clean and more maintainable. This is the power of react Hook form library. 122. Form Validation: So in real world application with building form, we have to also apply form validation for our form. So let's first understand what is form validation. Form validation is a technique to ensure user enter data correctly or not. For example, here we have our name filled and user enter only two characters, then we have to show error to user, like name should be three or more characters. We face this type of error many times. This is called as form validation. To apply validation using react hook form is very easy. Set the second parameter, we pass here our validation object and inside this, we add validation property like required to two and min length to three. Save the changes and take a look Without writing anything, click on submit and see here we get nothing because react hook form will only submit to form if all fields are validate. If we write three or more characters, only then our submit function run. Now let's see how we can get errors of our form. So for that, we have one property called form state in this use form hook. Add that here and simply Consol log this form state. Save this and take a look refresh the page and see here you get object and inside it, we have a couple of properties like errors is loading, is submitted, is valid, and so on. Let's simply print formstate dot errors. Save this, refresh the page. And see currently we have empty object. And the moment we submit to form, we get here error with name property. And inside these, we get type of that error which is required. If we write here one letter, then we get another error with type mean length. So by using this errors object, we can display errors. So after our input box, we add one emphasis tag and give it a class name, form, underscore error. And inside this, we add, please enter your name. Now we want to show this error only if we have error of name. So wrap this emphasis with Cl brackets and add here condition formstate dot errors. Now, instead of writing Fmst dot errors, we can destructure the errors property from Form state. So at the top, we add here colon and here we get errors. Remove this console dot log. We don't need that. Now at the bottom, we can use errors dot name, question mark dot type equals to required. If it is true, then only we show this error. Now you might ask why I add here question mark. This question mark and period is called as optional chaining. We need this because the errors subject can be empty, which means if we have no errors in this name field, we don't get errors dot name property, and if we don't have this errors dot name property, then we want to access this type property, then it will give us error. This question mark will tell browser if errors dot name is available, only then check this condition, otherwise, ignore it. Now, let's add error for mean length. Duplicate this line and here we add mean length. And also change this error message to name should be three or more characters. Save the changes and take a look. Submit a form and see here we get this error message. Please enter your name. And if we write something, then error message will change to name should be three or more characters. And if we write three or more than three characters, then error goes away, and that is pretty cool, right? Let's change this error color. So in login page dot CSS file at the bottom, we add dot FM underscore error. And in Cali brackets, we add color to red. Say the changes and see, here we get error in red color. 123. Form Validation based on Schema: So in the previous lesson, we had the form validation in between our markup. Now, if in future, we have complex form, then our markup gets really complex and our code will no more maintainable. So in this situation, we can use another technique called schema based validation. So in schema based validation, we can keep all our validation rules in single place. There are a couple of libraries like Yup and Zod. Currently, Zod is very famous, so we will use that. Open up terminal and in the new terminal, right NPM, I Zod. Or if you want to install the same verson which I'm using, then you can add here at 3.21 0.4 and hit enter. Nice, minimize this terminal. Now at the top of our component, we import one method called Z from Zod. By using this Z, we can define the schema for our form. In simple words, schema is a set of rules for fields. Now I want to change our form fields to email and password. I just use name and font fields to explain you about form. So in our form, we change this label to email, also here email and also change this ID to email. And inside this register function, we also change this to email. And here we can also change input type to email. Change this placeholder to enter your email address. Now, after this, we change this phone to password. And also here password, type to password, ID to password, and placeholder to enter your password. And in this registered function, we also pass password. Now, let's define schema for these two fills. So at the top, we at z dot Object. Now inside this function, we have to pass object, which have all fields and also rules for that fills. So our login form has first email, which is string, so Z dot string dot email. This method will check our email is valid or not. And also, we will set minimum to three characters. So here we define three rules for our email field, string, email, and minimum three characters. Now same we do for password field. Z dot string, and mean to eight. If you want to apply more validation rules, then you can check out Zo documentation. It's really simple. Here we have ready our schema perform fills, so we can store it in variable called schema. Now you might ask, how can we apply this schema to our form? So for that, we need one more library called Hook Form resolvers. So open up terminal and write NPM, I at Hook Form slash resolvers. At 3.0 0.1, and hit Enter. By using these resolvers, we can easily add our or schema in our react hook form. Now at the top, we import ZR resolver from hook form, slash resolvers SOD. Good. Now in our use form hook, we pass here object, and inside this, we have property called resolver, and here we add ZR resolver, and inside it, we pass our schema now let's quickly recap what we have done in this lesson. So first of all, using Z method, we create our validation schema, which is a set of rules for form fills. And then using Zod dissolver, we apply this schema to our react hook form. So when we have errors, it will directly add to react hook form error. Simple as that. Now let's see how we can display these errors. So first of all, in register function, we can remove this validation object. We don't need that. Also we can remove this one condition, and here we don't need to check for this error type. Instead of that, we can do something like this. If we have errors dot email, only then we display error. Also at the place of this hard coded error message, we can use errors dot email dot message. This message is the default message which added by Zod, but we can also customize so let's copy this piece of code from here and paste it for password filled. Now at the place of this email, we add errors dot password and also errors dot password dot MessagE. Save the changes and take a look. Refresh the page, and don't write anything and submit it. See here we get error message like invalid email and string must contain at least eight characters. The email and password fills and submit it. See, here we get our data, so it's working. Now, let's customize this error message. So to add our custom message, we can pass here object with message property. And pass here message, please enter valid email address. Also for this password, we pass Object and message to password should be at least eight characters. Save the changes and take a look, refresh the page, and submit the form. See, we get our custom validation message, so you can see how simple and easy to handle form and validation using react hook form and SOT Library. 124. Exercise for Forms: Now it's time for little exercise. I want you to handle this sign up form with react Hook from library and also add validation for these input fills. Don't worry about handling image input, handle input fills and add validation for them. This is very easy, and I know you can do it. Here is the validation custom message details, and by using these, you have to add validation rules. Now, before you start this exercise, I want to give you the signup page because in this section, our main focus is on form. So open the resources folder, which you download at the beginning of this course and open Project three folder and go to Form exercise folder. Here, I added signup page component and also the CSS file. So se like this two files and drop these files in the authentication folder. Now let's add this page in our app component. So comment out this login page and add here sign up page, and we are ready to go. At the bottom, I also add validation message for this form. So spend some time on this exercise, and then come back and see this solution. 125. Solution of this Exercise: Now, let's see the solution of this exercise. I know you solve this exercise, and if you stuck on something, then don't worry, you can learn now, but at least you try and that is more important. So I will not take much time and directly show you the solution. So first of all, at the top, we input use form hook from react hook form library. And inside our component, we call this use form hook. And store that in constant and directly destructure the register method and also handle submit method. Now in the name input field, we add register function and pass here our fill name, which is name. As we know, this register method return couple of attributes and events. To add that, we have to spread this. Let's copy this and paste it into all other input fills. Press Alt or option, and by clique, we create multiple cursor and simply paste it. Now for email, we add here email here we add password. After that, confirm password, and at last delivery address. Now, let's handle the submit. So in our form, we add on submit event, and inside this, we call this handle submit function. And inside this, we pass our function, call on submit. Now, let's define this function. So cons on submit, and we get here form data, arrow function, and let's simply consult or log this form data. Save the changes and take a look, fill this form. And click Con Submit. C, here we get our data. So we successfully handle our form. Now let's add validation using Zod. So at the top, we import Z from Zod and also import ZR resolver hook form resolver Zod. Why we need this ZR resolver right for applying schema with react hook form. Now let's create schema for our signup form. So we write z dot object, and inside this, we will add our validation object. First field is name, which is Z dot string dot Min 23. And here we pass our custom error message. So Object message to name should be at least three characters. Next, we have email, which is z dot string, so dot email. And inside this, we pass message. Please enter valid email. After that, we add password, which is z dot string. Also mean to eight and pass here custom message to password must be at least eight characters. Now for confirm password, we just add z dot string. I will explain to you why in just a minute. And at last, we have delivery address, which is also string and also mean to 15 characters. And pass here, our custom message to address must be at least 15 characters. We need to compare our password with our confirm password filled. So for that, after this object, we add refined method. Inside this, we can add callback function, which has data parameter. Just see this and your allots will go away. Now here we pass condition, data, which is the current object of our form fill, dot password equals to data dot confirm password. Now for this, we can also pass custom message at the second parameter. Message to confirm password does not match password, and we need to add one more property called path. And here in square bracket, we add our field name which is confirmed password. So basically, this means if data dot password and data dot confirm password is not same, then we get this error message for our confirm password field, simple as that. So here we have schema ready. So let's store that in variable called schema. Good. Now, we have to just add this schema in our react hook form. So in use form hook, we add object, and inside this, we have resolver, and here we call ZorRsolver and pass here schema. Now let's simply display these validation errors. So in this use form, we get form state, and here we can destructure errors. Now, below this name input, we add Cali packets, and here we add if errors dot name is true, then we display emphasize tag with class name, form underscore error. And inside this, we add errors dot name dot message. Copy this condition and paste it below all other input fills. Now, for email, which in this to errors dot email for password, which in this to errors dot password. For confirm password, we change this to errors dot confirm password. And at last for delivery address, we change that to errors dot delivery address. Save the changes and take a look, submit a form and see here we get all validation message. Now fill complete form and click on Submit. See, we get our input data. You can see how quickly and easily we can handle form and validation using React form and ZO library. 126. Handling Image upload: Now let's see how we can handle form with image of load or any file upload. So there are multiple ways to handle image of load. I want to show you my favorite and easiest method. So here, first of all, we will create one state variable using ust snippets and give it a name, profile peak, and set profile peak. And as default value, we pass here null. Also at the top we have to import state from react. Good. Now when we add our image, we will set it in profile peak state, same as we do with input fills. So in this file input, we add unchanged event, and here we get event object, arrow function, and set profile peak. Et target dot files. In this files, we may have a of list. Here, we just need first image, so index to zero. Now let's see what we get in this profile peak. Simply console dot log, this profile peek, save the changes and take a look. Refresh the page, and first, here we get null, which is the default value. Now let's upload image and see here we get our file object, which has a couple of properties like name, size, type, et cetera. So when we have to upload image to server, we have to send this file object to our back end. Don't worry, we will see that in the next section. For now, let's focus on handling image upload. We successfully getting this image object. Now we have to only display our selected image inside this image preview. It is really simple. Let me show you. Here in the image source at the place of this user, we add here one condition. If profile peak is not null, then we will render our profile peak, else we stick to our default image which is user. Set the changes and take a look, repress the page, and upload an image. See here our default image is gone, but we are not getting our selected image. The reason is here, we simply return our profile pick object, which is not the image. We have to convert this object to image, and how can we do that simply by using creat Object URL method? So aral dot create Object URL is a method in JavaScript that allows us to create a unique URL for a given file. This URL is used to display image in image tag or playing audio or video file in Media Player. Note that this is only temporary URL, which means if we close our page, then it will go away. So at the place of this profile peak, we pass l dot create Object URL and inside this, we will pass our image object, which is profile Peak, save the changes and take a look. See, here we get our selected image. You can see how simple and easy it is to handle image upload in react. Now with this, we complete our advanced form section. Now in the next section, we will connect our react application with the actual back end which I created for this project. S in the next section. 127. Section 12 Connection to the Backend: Welcome to the 12th section of the ultimate react course. In this section, we are going to connect our react application with the back end. I created this back end, especially for this application using nodejs, express Js and MongoDB because with most of all react application, developers like to use these technologies. Here, I want to clear one thing we are not creating Bend because it is not the scope of this course and our main focus is on learning react. In the next lesson, we will install Mongo DB in our system, which is the database. If you have already Mongo Di B in your machine, then also in my suggestion, try to install latest version of Mongo Di B. Let's start this section. 128. Install MongoDB & Compass in Windows: So let's install Mongo Di B on Windows. If you have Mac, then you can skip this lesson. So first of all, head over to mongodib.com and *** over these products. Then in Community Edition, select Community server. Scroll down. And here, we can select MongoDB version. In my recommendation, please don't change it. Next, we can select our platform, and then we can select package. Don't worry about that. Just click on Download. See how download is started. Now, after completing the download, open that setup, and it will ask for installation permission. Allow it. Click on next, accept the agreement, click on next, click on Complete. After that, from here, you can change your installation path. But if you don't have any reason, then don't change it. Just click on next. Make sure to select this install MongoDB compass, which is the application for Mongo DB in which we can view all database tables and edit or delete DM. Click on Next and install. This will take some time around five to 10 minutes because we are also installing Mongo DB compass. After completing the installation, let's verify this. So on command prompt and write Mongo and hit Enter. We get this error. Mongo is not recognized as an internal or external command. So to solve this error, we have to again go to Mongo DB website and here at the top, products and in tools, SeaclNw click on download now. And just download this. Now open the download folder and extra dot zip, which we downloaded. Open that folder, and in Bin folder, we get this Mongo's x file. So copy this and open C drive. Program files, MongoDB server, 6.0 bean paste it here. These Mongos is our MongoDB cell. Now we have to do only one last step, which is setting the path to environment variable. Copy this path in start, search for environment variable and open edit the system environment variables. Now click on this environment variables and in system variables, select path, and click on Edit. Now we have to add that bind path here, click on New and pace that path. Click on Okay. Okay, and Okay. Restart your command prompt and open it again. Right here, Mongos and hit Enter. We will get the Mongo Di B cell, so we successfully install Mongo Di B in our system. Now, let me give you a quick tour about Mongo DiBe compass. So when we open this application first time, we have to enter our connection string, which is Local host. So write this connection string, which I write and click Ccnect. See, here we get all our database and tables. 129. Setting up backend: After we install MongoDB and Mongo DB compass in our system, it's time to set up our backend and fill data in the database. Now you might ask, what is the need of this backend and why we are adding data in our database. So previously, we seen how to call public API in react. But as we create website for company, many companies have their own backend. So I created this backend for our application, and also only backend is not needed. We have to store our products data and users data in our database. So we can get that data and display them on our application. Currently, in our Mongo Di B Compass, we can see we have only system generated database. We have to add our own. Open up resources folder and in Project three folder, we have cartwis back end. Open that and open it in VS code. Now you don't need to worry about anything inside this back end. Just do as I'm doing and you are ready to go. So first of all, we have to install all packages. So open up terminal and write NPM install and hit Enter. Now in this data dot JsNFle, I add some data for products and categories. So to fill this data in our database, we just write here node products, dot js file, and hit Enter. And see here we get database filled or restored successfully. Let's verify this. Switch to Mongodi we compass and refresh the database. And here we can see Catews database. Open that and inside this database, currently we have only two tables, categories and products. Open the, and here we get these categories data. And if we open products, then we get products data. From here, we can view, update, and delete these records. Now we can minimize this Mongo D B coompass and in our Ben VS code, we run node index dot js and hit Enter. C, we get server is running on port 5,000 and also database connected. Let's verify this API is working or not. Open up new tab in the browser and in the URL, write local host Column 5,000 because our backend is running on the local host 5,000 API category, and hit Enter. See, here we get this array of all categories, so it's working. Don't close this terminal. Without this terminal running. We can't connect our react application with Ben. So make sure it is running while we are making API calls. 130. Implementing Routing in our Application: Now, before we start patching data, let's implement routing in our application because currently we have to manually add components in our app component. So open up terminal and in the new terminal, we write NPM, install, react router Dom at 6.11 0.2 and hit Enter. Good, minimize this terminal. Now, what is the first step to apply routing? Right, we have to wrap our application with browser router component. So open up main component, and at the top, we import browser router from react Router doom and wrap our app component with browser router component. Save the changes, and now open up app component. Here we have all our pages which we created, and that's why I told you to comment out these pages here, so we don't forget to add any page component. Also, let's define all routing in a separate component. Otherwise, our code will become ugly. In components folder, we add one more folder called routing, and inside this routing, we create a new component called routing dot JSX. Let's add here boilerplate, and at the top, we import, first of all, routes and route from react router doom. Now let's remove this due and we add here routes component. And inside these routes, we can add our single route component. But before that, let's add all imports from app component. Here we cut these all imports and paste it in our routing component. Good. Now let's define route. So first of all, route path to slash, which is home and element to home page. Now after that, we add another route path to slash products and element to products page. Now duplicate this route five more times. And here we add path to slash products and element to single product page. Next, we have path to sign up and element to sign up page. Next, we have path to login and element to login page. Next, we add path to cart an element to cart page. And at last, we had a path to my orders and element to my order page. Save the changes, and let's set this routing component in our app component. So remove these all pages and simply add here routing component. As a developer, in my humble opinion, you should always try to take step by step approach. Don't try to implement all functionality or task in one go. By doing that, you stuck less and you can think more clearly. Save the changes, and let's see how routing is working or not. See, here we are getting error. It's because we enter wrong path. So in the routing component at the place of this period slice components, we have to add double dot. Select this and press Control plus D or Command plus D for multiple cursor editing and add here period. Say the changes and take a look. See, here we get our home page. Now click on Products page and see, we get products page, so it's working. But we have to replace these links with NewLink component. So p Never component, we have these all links in link with icon component and this one link in anchor tag here. So let's replace this anchor to Newlin component and replace HRF to two. Save this and in ink with icon component, we replace anchor with Newlin component and HRF 22. You can see how easily we can modify our code. And that's why we store this link in separate component. Save this, and let's add CSS for active Link. So in Navbar dot CSS file, here, we add dot NabarUnderscoe inks, angle bracket, anchor, dot Active Coli brackets, and we set font weight to 600. Say the changes and take a look. Switch the pages and see here we get our routing. 131. Fetching Products: Now, let's call our first API for Getting all products list. And for calling API, we will use Axos, open up terminal, and write NPM install XOs and hit Enter. Minimize this terminal and let's first define our API base URL for each request. So in the source folder, we create a new folder called Utils and inside this folder, we create a new file called api Client Js. This is for making STDPRquest using Xos. Remember, we already created this. Inside this file, we input Xos from XOs and after that, we write Xos dot RET pass here our configuration object. In this object, we have base URL property. And here, we can pass our base URL. So here, our base URL is SDDP column, double forward slash local host, Column 5,000 slash API. Now here we can also pass our API headers which you want to send with our API request. Again, it depends on API. If you are front end developer, then you get this all API details By Backend developers. You don't need to worry about this. I will link our API documentation in the resources folder, or you can download it from attachments. Now let's export this as default. Save this. And now when we want to make API request with AXIOS, we simply input this API client and do same as we do with original XOs. So when a product page, here we need to decide where we need to call API for products. So in our products list component, we are displaying all our products. So we can call our API here. So first of all, in this component, we need to create one state variable for storing products list. So write use and press tab for importing ust and write us snippets and give it a name, products, set products, and as default value, we pass here empty array. Now also create one more state variable called error and set errors. And as default value, we pass empty string. Now, in which hook we call our products API, we call our API in use effect hook because we need to get data when component gets surrender. So, use effect and inside it, callback function and second parameter is for dependency array. Now, let's call our API. At the top, we import API client, which is just defined from Utils API client. Now, let's add here API client dot Get now inside this, we pass our URL, which is slash products. This expression returns a promise. So then response, arrow function, set products. Now here we need to pass our products array. So to check this response, open new tab in browser and write our GAT method. Local host, Column 5,000 API slash Products and hit Enter. And see here we get this response object with a bunch of properties. For now, let's don't worry about this. We only do one task at a time. So back to VS code, and here we pass response dot data, which is our object, and we get here dot products. Now for handling errors, we add catch method, and here we get error, error function, and set error to error dot message. Now let's see we get our products data or not. Save the changes and back to our application. Open developer tools and open up component step here. Search products list, and here we get our products list. Select the and see in this state, we get our products array which has eight products, so it's working. Now, let's display these products in card. So at the place of the multiple product cards, we at products dot MAP here we get single product, error function, and we simply return product component, and don't forget to add key attribute to product dot underscore ID, which is the unique ID for all products. Save the NGs and take a look. See, here we get eight products card. Let's handle error for this API request. So before this product list, we add one condition. If error is available, then we print that error here. So emphasize tag and give it a class name for error. And here we add this error. Now, let's generate error. So at the place of this API URL, we make Typo, save the changes, and take a look, repress the page and see here we get this error. Perfect. Let's remove this typo. Now in the next lesson, we will make our product card component dynamic. 132. Making Product Card Dynamic: Now let's make our product card component dynamic, open up single product object, just to see what is inside this. Here we have reviews, which we display here, underscore ID, title image is array. We don't need array, we only need first image for poster. Now, after that, we have price and stock. So product card component, and here, first we add all props we need in this component. St structure props. First we get ID, then images. After that, we need price. After that, title, rating, rating counts, and at last, we need stock. Now let's replace the static values by these props. At the place of this iPhone, we add image. After that, here we add price. Then here we add title. After that, rating and here, rating counts. Now we will only show this head to card button if stock is greater than zero. So see like this button and press left curly bracket. This will wrap our code in CLI brackets. If you press right culi brackets, then this code will replaced with right culi bracket. Here we pass condition. If stock is greater than zero, then only show this head to card button. Now at the top, sorry, we forgot to add product ID into this link. So we remove this anchor tag and add here New link or link component and attribute to curly brackets, Batak, slash product, slash dollar ID. So we are done with product card component. Now we just have to pass these props to product card. So at the top, we remove this image import, save this file, open product list component. Here after this key, we pass ID to product dot underscore ID, image to product dot Image and here we get first image. Price to product dot price, title to product, title, rating to product dot revs dot Rate. Rating count to product dot revs dot counts. And stock to product dot Stock. Save the changes and take a look. See here we get all details, but we are not getting image. Let's see why we are not getting this image. Right click on the image, select image, open up this DU and in Anchor tag, we have our image. Here we can see we are passing only image name in source. We need to pass image URL here. I already had details about that in API documentation. So in our product card component, at the place of this image, Bates, here we add HTTP, column double for our slash, Local host, Column 5,000. Slash products slash here we add our product image name. So dollar image, set the changes and take a look. See here we get our image. 133. Fetching Categories: Now let's fetch all categories and display them on this side bar. So on products side bar component, and here we also do the same for fetching data. First of all, we create State variable using ust Hook and give it a name, categories and set categories. And as default, we pass empty array. And after that, we create one more state variable called errors and set errors, and we pass empty string as default value. Now, let's call our API in use effect hook. So use effect, and inside this, we add callback function, and here we just add empty array as dependency. Now at the top, let's import API client for calling API. Here we go to fullers up, Utils and API client. Good. Now here we call API client dot Get method. Here we pass our API URL, which is slash category and we know this expression returns a promise. We handle promise with then method. Here we get response, arrow function, and set categories to response dot data. Now for handling error, we add cache method. Here we get error, error function, and we set error to error dot message. Save the hinges and take a look. Open up developer tools and open components tab. Search here products side bar and see here we get our categories. Now let's display them on our page. So back to VS code. And here we add categories dot MAP. Inside these, we get single category error function, and we simply cut this link with icon component and return it here. And before we forget, let's add Key equals to category underscore ID. Now we change our title to category dot name. And we wrap our link with Cali brackets and we change this to Batis and at the place of this electronics, we just add dollar Cali Brackets, category dot name. Now at the place of this image E, we pass our image URL. So in taxes, STDP, Column double four, slash, Local host, Column 5,000, category, slash and here we add our category image. So category dot image. Save the changes and take a look. See, here we get our categories. Now let's display error. Before our category list, we add condition. If error is available, then print error in emphasis tag and class name to form error, and we simply add here error. Now here, let's make Typo, save the changes, and take a look, refresh the page and see here we get our error. Remove this typo and see we are getting our categories. 134. Creating Fetching Custom hook: Now, as we can see, fetching products and fetching categories are almost the same. Just the difference is, this is a PIURL. So we can create our own custom hook, which we can use for almost all fetching details. Some developers think custom hooks is a scary concept, but it's really simple. So custom hooks are basically a reusable function. In simple terms, custom hooks are our own hooks that we create for our own use, and we can use them multiple times in our project. Let me show so here in the source folder, we create one more folder called Hooks. Now, in this folder, we create a new file called sedata dot js. Now you might think, why I use here dot js extension instead of dot JSX. So the reason I use hear dot js extension because in this custom hook, we are not going to use any JSX. We will write our logic in plain JavaScript. Let's set boilerplate code and remove this return statement. We don't want to return JSX here. Now from our product side by component, we cut the date variables and use effect hook from here and paste it in our custom hook component. Now at the top, we import use effect and used it hook. And also input API client from Utils API client. Now, as we are using this custom hook for getting data from API, it's better to rename this data variable name to data. So see like these categories and Press F two, right here, data. And also rename these set categories to set data. And here we pass null as default value because we don't use this data to store only array. We can also store object in this data. Now we have to just change this API URL. So we replace this URL with URL variable, and also we get this URL variable as parameter. Good. Now from this custom hook function, we simply return data and error variables. Save this file and in product sidebar component, here we simply call our custom hook, use data, and pass our endpoint, which is slash category. Now, this hook return object with data and error. So we can destructure that object and get here data and error. And also, we can rename this data as categories. And here before our map function, we add one condition if categories are not null, only then run this map function because default value of this data is null, and we don't want to run map method for null. It can give us error. Now, let's remove these unwanted imports, select the import which you want to remove and press Control plus period or Command plus period and select delete all unused imports. See, all unwanted imports are gone. Also, let's remove this. Save the genes and take a look. See, we get result same as before. Now let's use our custom hook for getting products data. So one product list component and remove these variables and use Effect Hook. And here we call use data hook and pass and point to slice products. Will return data and error, and we can rename this data to products. And we can also add here condition if products is not null, only then run this map method. And at last, we remove these all unwanted imports and also remove these curly brackets. Save the changes, and we get error. Let's open Console and see here we get products dot Map is not function because in our use data hook we store our response dot data in this set data function. But from products API, we get response object with a couple of properties. Do you remember, let me show you. So simply consult dot log these products here. Save the changes and take a look. See, here we get this data object. And in that object, we have products array. So we can use here data dot products, or we can restructure this data object and get here products. I think restructuring is a little confusing for us. Let's remove this now at the top, we change these products to data dot products and also here data dot products. And at the top, we simply console dot log data to this data. Save the changes and take a look. Currently, we are getting our products. Now let's refresh the page and see we are getting error. W developer tools and in the console, we are getting the error, cannot read property of null. Let's see what is happening here. First of all, in our use data hook, we pass null as default value. Now at the time when our data is null, here in this condition, we are trying to access data dot products, and that is the reason we are getting this error. And after that, fetching data from back end, we are getting this data in our console. So for that, we can put optional chaining in this condition. So if data question mark dot products is available, only then run this loop. The changes and take a look. See, now our code working well. So you can see how we can solve error by simply breaking it in little little part. First of all, we have to know why we are getting this error, and then we need to find the best solution for that. Don't get panic by seeing errors. Errors will always occur. It's on you, how you handle it. 135. Adding Loading skeleton: Now currently our product page working fine. We have good Internet connection, and also we are getting data from local server. So we are getting data very quickly. But imagine if user connection is slow or our server taking long time, then this product page doesn't look nice. Let me show you. Open up Console and we are getting here warning. Let's see here we are getting key is missing. So in product side but component in this link with icon component at the top, we add key attribute and pass here category dot underscore ID. Save this and see here warning is gone. Now open up Network tab, and here we select pass three G. Refresh the page. And here we can see not look good without while we are fetching, we can show loading skeleton. It's look like. You can see almost all modern websites has these loading skeletons. So let's first create this loading skeleton. So in our product folder, we create a new component called product card skeleton dot JSX. Let's set uprate code. Now for creating skeleton, we can use CSS or we can use Library. Choice is yours. What do you want to use? I like to use library because it's easy to use. If you want to create skeleton from scratch, then you can watch these tutorials. I will drop Link in Resources folder. And in the new terminal, right NPM loading skeleton and hit Enter. Good. Now at the top, we import skeleton from react loading skeleton library. And after that, this file. So it will add CSS tiles for this skeleton component. So Import reac loading skeleton, dist skeleton dot CSS. Now, from this component, we simply return this skeleton component, and let's see what we get. Save this. And in our product list component in this product list die, we add our new component product card skeleton. Save the changes and take a look. See, here we get little loading skeleton area, but we can't see it. So for making it big, we have to add styles for that skeleton component. So back to our skeleton component, we can add here styles, and we can also add class so we add class name to product underscore card. And for this skeleton, we have to add width externally because by default is skeleton, add width 200%. Let me show you. Save this and see here we get all other properties, but not width. You can verify it by inspect. So back to our component and add here with 275 pixel. Save the changes and take a look. See, here we get this skeleton, same as product card. Now, let's add multiple loading skeleton. In product list component, we can duplicate this skeleton multiple times, but that is bad practice. So at the top, remove this log, and here we create one array called skeletons and pass here one, two, three, four, five, six, seven, and eight. Now in our JSX, we add skeletons dot Map. Here we get each number and simply return this product card skeleton. And pass here, key equals to number. Save the changes and take a look. See, here we get eight loading card. Now let's sell loading logic. So in our use data hook, we create a new state variable call is loading and set is loading. And as a default value, we set it to false. Now, here before we call our API, we simply set E loading to true. And after we get our data here in then method, we add Cd block, and here we set is loading to false. Also, we set Es loading to false if we get error. So add here code block and set E loading to false. Good. Now we can simply return Es loading from here so we can access it in our components. Save the changes, and in product list component at the top, we destructure here is loading property. And here we simply pass condition if es loading is true, only then we show these skeletons. Save the changes and take a look, refresh the page and see how nice it looks with this skeleton loading. This is how little features add more impact on user experience. 136. Fetching products by category: Now currently we have our products data and also categories. Now when we click on any category, we want to fetch products according to that category. I think we made mistake in this link. So back to VS code and in the product sidebar component here in this link, we have to add slash products. If we add only products, then it will add this link in current URL like this. So don't forget to add this forward slash. Save this and back to our page, click on category. See it is adding query string. Now we want to fetch products by this category. So back to product list component, and at the top here in our API request, we have to pass just category as query parameter. Now you might ask how we can pass query parameter. So there are two ways to do that. We can simply pass our category in our endpoint like this. Or we can pass Configure object in this use data hook. Choice is completely yours. I personally like to pass configure object because for now, we have to only pass query parameter. But if in future, we want to pass something more, then definitely, we need to use configure object, and at that time, our code gets messed up. So it's better to use configure object. So in this use data hook, we pass object at the second argument, and inside this, we pass params, which is the object, and here we can pass all our query parameters. So category two for now, let's pass laptops. Now we have to add this object in our use data hook. Save this file and open us data dot js file. And here we get Configure object, and we call it a custom configure. Here also, we change this URL parameter name to endpoint. I think that could be more specific. Now here we change this URL to endpoint and simply pass our custom configure object here. Simple as that. Say the changes and take a look. See, here we get only laptop details. Now, in our product list component, if we pass here smartphones, then we only get data of smartphones. So we successfully pass category query string in our API call. Now at the place of this hard coded value, we have to pass category from URL. Do you remember how we are getting query string? Right? We use use search params. We have seen these in routing section. So here we add use search params, and this will return all query parameter. So cons to array, and here we get search and set search. Let's get category query string from this search. So Const category equals to search dot gt. And here we pass our query string name, which is category. Now at the place of these smartphones, we add category variable. Or we can also remove this category. Why? Because name and value both are same. Save the changes and take a look. Refresh the page and see, here we get our gaming consoles. If you change to headphones, then refresh the page. See, here we get all headphones products. So it's working, but we have to refresh every time when we are changing category, and that's not the good thing. So let's fix this. So here, we have to pass this category as dependency in our's so in this use data hook, we pass dependency array at third parameter and add here category because we want to recall use effect when category will change. Say this and in use data hook, first, we get dependency array as deps and at the place of this empty array, we pass deps. Now if we adhere only deps, then in all user data function, we have to pass dependency array, which we don't want, right? So here, we simply put one condition. If deps is available, only then add deps, else, we add empty array, simple as that. Save the changes and take a look. See, now we don't need to refresh our page. We can navigate from category to category. 137. Pagination: Now currently, we only getting eight products, but in database, we have 24 product details. Why I return only eight data from server? It's because this is a technique by which we can reduce the load of data in API. Let me explain to you why. Currently, our application is very small. 24 data is not a big deal. But imagine as our application grow, we might have 1,000 or 10,000 products like Amazon. So at that time, if we get all product details in one API call, then it will take more time, and that will not give user better experience. So instead of getting all data in single request, we developers divide them in pages like we get only eight or ten data in single request. If user need more data, then we fetch next ten data. So here is the page initiation we are going to create. On first page, we have only eight records. After that, when we click on second page, we will get next eight data, simple as that. So far fetching other page data, we have to pass only page parameter inquiry string and set to that page number. Let me show you. So go to the products page. You can note these products. And now in our Param subject, we add page to let's say two. Save the changes and take a look. You can see here we get another eight products data. If we change page to three, then we get another products data. Now at the place of setting this page hard coded, we can also get them in our query string. So here we write Cs page equals to search dot get. And here we pass our parameter name, which is page. So now we can set page to this page. And for simplifying, we can remove this page. Don't forget to pass page in this dependency array. Otherwise, when we change page number, then use effect will not run. Save this. And now let's see how we can set page number in our query string. So for that, here we have set search function. So for Demonstrate temporary, we create one button below this product list called page two. And on button click event, we pass arrow function, and here we call handle page change. And pass here our page number, which is two. Now in this function, we will write our page logic and set page parameter to this page number. Let's define this function at the top. So const, handle page change. Here we get our page as parameter, arrow function, and inside this, we simply set search to object, page to this page. Let's see it's working or not. Back to products page and click on this page to button. See, we get the second page data, and also in our URL, we can see page two. Now here is one little bug, select any category and then click on this page to button. And see we are again on our simple products page with page two. You can verify it by see this URL. See, when we click on any category, we have category in our URL, and when we click on Page button, our category is going away and only we get page to two. Why this is happening, let's check this. So in our handle page change function, we set surge to this page only. This will replace all other query parameters from URL and set page two. So to solve that, we have to add all previous value to this set search function. And then we have to add page two. So before that, we create new variable const, current params, equals to object dot from entras. And inside this, we pass array, and inside this, we will restructure the search. Let's see what we are getting in the current params. So console dot log the current params. Save the changes, open up Console and select category, and then click on page two button. C in Console, here we get that category. This expression is returning query string object, which is available in this search string. So we can simply add that object using objectstructuring before this page. Save the changes, and here we can see we change category and click on page two, then our URL has all query string. You might ask why we are not getting data here. It's because in this category, we don't have page two, which means products are less than eight in this category. But in the URL, we can see our category is still there. So we have done our pagination logic. Now we only need UI for pagination, which we create in the next lesson. 138. Creating Pagination UI: Now, let's create Pagination component for adding Pagination UI. So in the common folder, we create a new file called pagination dot css and also create a new component called pagination dot JSX. The reason we add this pigeonation component in common folder because we can use it in any other components. Here we add boilerplate code, and at the top, we import period pigination Css. Good. Now what we want from this component. We want only page numbers from this component, and this component decide how many page we need to show. For example, if we have 100 products and we want to display eight products per page, then we need 100 divide by eight, which is 12 into eight, which is 96, and we need one more page for other four posts. So overall, we need 13 pages. Another example, if we have only seven products, then we don't need to show pagination. So we have to handle these logics. And for that, we need to pass three variables. First, we need here total post, post per page, and click function, which we can run on button click. So here we create one variable for storing page numbers. Page equals to empty array. Now after that, we add four loop to fill this array with page numbers. Here, let I equals to one. Next, we write I ser equals to total post, divide by post per page and I plus plus. Now we push this I in this array, so write pages dot push and here we pass I. If our total post are 80 and post per page is ten, then we get ten pages. But if we have total post 25 and post per page is eight, then 25 divide by eight, which is 3.125. We get only three pages and that's not we want. To solve that, we have one method in JavaScript called math dot Cal, which will round up our number to the nearest integer, which means if we pass here 2.05, then it returns three. So we wrap this equation with this math dot seal method. We just have to return this page number button. Here, we create one unordered list and give it a class name page nation. Inside this list, we display our button in list items. Pages dot Map. Here we get each page arrow function, and here we return list item, pass key to page. Inside this, we add button with class name, pagination, underscore button. And onclick event to arrow function. And here we call onclick function, and pass here our page number. And inside this button, we simply display page number. Save these, and let's add this component in product list component. So open product list component at the bottom, we remove this page to button, and after this D simply add our page inan component. Remember, we have to pass three props. First one, total post, which is data dot total products. Post per page to eight and on click to handle page change. Note that here we are only passing reference. We calling it in our page nation button. Save the changes and take a look. See, here we get our page Nation buttons. Click on button two, and see, we get second page. Click on page three, and we get page three, it's working. Now here we have little bug. If we set our category, then for only three items, we are getting this page one button, which is okay, but I don't like it. In our pagination component, we pass here one condition. If pages dot length is greater than one, only then we will return this pagination list. Here we get compilation error because if pages dot length is not greater than one, then this component will return nothing. We can wrap this code with react fragments. And r is gone. Lovely. Now you might ask why we don't add condition in our product list component. So the reason is if tomorrow we use this pagination component in another component, then we also need to pass condition there, and we don't want that. So that's why I add condition in this pagination component. Save the changes and take a look. See, it's gone for less than eight products. If we redirect to products, then we can see pagination. Now, let's set style for these buttons. So in Pagination dot CSS file, first of all, we add pagination, and in curly packets, we add less style to none, display two flax, justify content to center, flax wrap to wrap. And margin to 16 pixel. Next, we are style for dot pagination underscore button, cli brackets, and inside these, we set width to 40 pixel height to 40 pixel, margin to zero and ten pixel font size to 16 pixel font weight to six and red, border to one pixel, solid has Ii ei, ei, border radius to six pixel, background color to white, color to black. And cursor to pointer. Save the changes and take a look. See, we get nice button. Now here we don't know which page is selected. So in our pagination component, in our button class name, we add condition, current page equals to this page. Then we return to classes, pagination, underscore button, and active. Else, we return only pagination, underscore button class. Now we have to also get here current selected page. So we add this current page variable in props. Save this and in our product list component, at the bottom, we pass one more props, current page to this page, which we get from use search PAMs. Save the changes, and let's at CSS for active button. So dot pagination, underscore button, dot active Calibracket, background color to black and color to white. And in this pagination button, we transition to 0.2 second is in and out. Save the changes and take a look. Still, we are not getting active class because this current page is string and this page is number. Here, we wrap this current page with method called parse Int. The changes and take a look. Refresh the page and see here we get error. Let's open Console. Here it is telling us cannot read properties of null. So when our data is null, we can't access data dot Total products property. So we wrap our pagination component with Cali brackets and pass here condition. If data is available, then only render pagination component. Save the changes and take a look. See, here we get our pagination number. Now we are almost done. We have one last bug. So here, when we change our page number, something is happening. Let me show you. So one network tab and put connection to fast three G. Now change the page number and see here we can see our loading skeleton, and also we can see our old post. So let's fix this. Open product list component, and here at the place of this end, we pass a ternary operator. So question mark and also remove this curly bracket. And here we pass Colon. So if e loading is true, then we display skeleton, else we display products. Save the changes and take a look. See how clean and pretty our page looks. I know this lesson is little bit long, but you can see how simple and easy it is to add pagination in our application. Just we need to set page in API query string. Lots of developers confused by pagination concept, but you can see how easy and simple it is. 139. Infinite Scrolling: Now, as we've seen, pagination is very important concept, but it is mostly used in database applications like blog website, education website where people are willing to give full attention. But if you are creating application like social media apps or something like Instagram or YouTube in that applications, we can't add pagination. These applications, we need to add infinite scrolling feature like this. If we scroll to the bottom, then we get next page data, and also we can see our previous data. So if we use infinite scrolling feature in our application, we can easily grab user attention even if user is not willing to give its full attention. And that's why people spend more time on social media because they have to only scroll. So let's understand the logic of infinite scrolling. Logic is very simple. When we reach to the bottom of our page, then we will increase our page count by one simple as that. So let's implement this infinite scrolling feature in our application. I'm not removing this pagination code. I just comment out this function and also comment out pagination component, so you can use it as reference when you need it. Now let's start with step number one, which is we need to add scrolling event, which will give us info when we reach to the bottom. So we create one use Effect hook for add event listener. Here we add callback function and pass empty array for dependency because we want to declare it only one time. Now inside this, we write window dot add event listener. Now pass first parameter, scroll, and the second parameter is function which we want to call on scroll event, handle scroll. Now let's declare this function, handle scroll in use effect hook. And inside it, we write our logic. So in JavaScript, we have a couple of elements for getting the data of Dom in document dot Document element. So here we destructure it and get here, scroll top. After that, we get client height, and last, we get scroll height. Now, let's simply console dot log these three variables. So console dot log, scroll top to Scroll top. After that, Console dot log, client height to client height. And at last, console dot log, scroll height to scroll height. Don't worry about these properties. See this and you will understand all of these. See the changes and take a look. Currently, we don't have scroll bar. So let's open developer tools, and in Console, here we have scroll bar for our page. And when we scroll, we get these values. Now scroll to the bottom, and for this, we want to put condition. Here, scroll top is a measure of how far down you have scrolled on a web page. Basically, it tells us the distance from the top of the page to where we are currently viewing. Now, client height is the height of our web browser window. It represents the visible area of the web page that you can see without scrolling. Scroll height is the total height of entire web page, including the parts that are not currently visible in your window. So in simple terms, the scroll top tells you how much you have scrolled down the client tells you the height of what you can see, and scroll height tells you the total height of the entire page. So when we reach to bottom of our page, this scroll top plus client height will always equals scroll height. So here in our scroll function, we add condition I scroll top plus client height greater or equals to scroll height. Here, I don't know why, but sometimes this condition will not work. To solve these, we have to just add here minus one. Before one pick L from the bottom, this logic will run. You can change this value according to your needs. Inside this function, for now, let's add console dot log, reach to bottom. And if you are not getting scroll bar, then you can pass here in the Perms object per page to ten. I specially designed this API so we can also get what we want. By default, I set per page to eight, but we can pass whatever we want to. Save the changes and take a look and see here we get ten products. At the bottom, we can reach to bottom. So it's working. Now, second step, which is we need to increase our page count. So let's use the same logic of our handle page change function. So remove this comment, and here at the place of this page, we add current PAMs dot pH plus one. Now call this function in our handle scroll function, or we can directly call that function without changing anything, and after that, we can pass current params dot page plus one here. But don't worry about this. Save the changes and take a look, scroll to the bottom, and we get nothing because here we are getting data of page 11. To fix this, we have to grab the current params dot page value, which is string into parse integer. Save the changes and take a look back to page one and scroll to the bottom, and we get our second page data, but our previous data is gone. So for that, we can do one little trick, open use data file, and in our API call, in then method, we can see we are directly setting this data into set data function. So instead of that, we can put here condition I endpoint equals to slash products, and we check if we have data is not null, and data dot products is available. Now, if these conditions are true, then in set data, we get here previous data, error function, and here we want to return only object. So in parenthesis, we pass object. Here we first add all previous object value and replace our products to array here, first, we get previous products data, which is spread operator, previous dot products. And after that, we add spread operator, the new products, which is response dot data dot products. And se we have other end points, then we simply set data to this data. If you are a little confused, then let me explain to you why we are doing this. So for only products request, and if we have already products in our data state, then we are getting object of four properties in which we have products array, but most of the other GAD request directly return array. So if we use the same set data for all request, then we always get our data in object and we get error. So that's why we have to put these conditions, save the changes and take a look. Back to page one. And scroll to the bottom. See, here we are getting new products with previous products. Now, one little weird thing is happening here. When we call our API, we don't see our previous products. So for that, in our product list component, at the bottom, we remove this ternary operator and we use and here curly brackets and also remove this column and add here curly brackets. Now move these products array before this skeleton. When we are fetching new data, the skeleton will display at the bottom of this list. Save the changes and take a look. And here we change our page to page one. Scroll to the bottom and see we get skeleton in bottom. Now we have another little issue in this implementation. In infinent scrolling, we don't need to show this page number in the URL. So for page at the top, We create a new state variable called page and set page. And as initial value, we pass here one. Now we can remove this page from here. We don't need it. Basically, this page value will replace by our page state variable, so we don't need to change anything. Just we change here this logic. So at the place of this handle page change function, add set page to here we get previous page, arrow function, previous page plus one. Save the changes and take a look. See, now we don't get page in our URL. Lovely. We are almost done with in fine at scrolling. Just we need to add cleaner function in this use effect hook because currently we are on product list page. If we redirect to another page, then also the scroll event will run and that will affect our application performance. So in our use Effect took at the bottom, we had written arrow function and simply copy this expression and just change this to window dot remove Event Listener. Save changes, and this works. Now let's recheck our products page. So refresh the page. We get products. Now scroll. Nice, it's working. Now at the top, selectny category, and we get that products at the bottom. Instead of that, we want to replace these all products by our categories product. So this is little Burg. Let's find this. Open up use data hook. And here in this condition, our endpoint is products and data dot products are available. Then we are adding new response dot data in previous array. But when we change category, this condition is also true, and that's why we are getting data at the bottom. We have to addhe one more condition, custom config dot params, dot page is not equals to one. Only then run this logic. Save the changes and take a look back to products page and repress it. Scroll page to the bottom, and we are getting next page. Now if we click on any of this category, then we will not get that products because we are currently at the page two, and in gaming console, we have only three products. So for page two, we don't have any products. So let's quickly fix these. So I product list component at the top, after our use data hook, here we add one use effect and pass here, callback function, and in the dependency array, we simply pass category. And inside this, we simply set page to one. So when category changes or removes from query string, then our page is set to one. And that's what we want, right. Save the hinges and take a look. Back to products page, and then se the category and see here we are getting our products for category. Now let me show you something. I don't know if you notice or not. When we reach to the bottom, sometimes it's loaded two pages together, or sometimes it continues to request even our all products patch prom database. So we need to fix this. So in our handle scroll function, here we add a couple of conditions. First one, if this loading is not true, another data is available and the last one page less than data dot Total pages. These total pages we are getting from server. And because we are using here our data and is loading variable, we have to edit in our dependency array, save the changes, and take refresh the page and scroll to the bottom, and our all issues are fixed, so that's how we can implement infinite scrolling feature to make our application modern and highly engaged. So you can see pagination and infinite scrolling feature are not that much complicated. Just we need to understand the basic logic of these two features. 140. Exercise Single Product Page: Now it's time for little exercise. Don't worry. This will take only five to 10 minutes. So when we click on any product, we redirect to single products page. And here we want to display that single product details. And also, we get that product ID in our URL. So you have to call this API with endpoint products slash Product ID at the end. This will return this product data here. And while we are getting that data, you can also display here loading text, or you can show here spinner, which you can directly use from our previous routing project. Next, don't worry about at two cart button. Just we have to handle this quantity increase and decrease number. Hint is, you have to create new state variable for handling quantity, spend some time on this exercise and then watch the solution. I know you can complete this exercise. 141. Solution of this exercise: So I hope you solve this exercise or you try to solve that. Most important is you try. Stucking at some place is very common. Sometimes I also stuck at some point, so don't worry about that. So in our single products component, we first need to get the current ID from our URL. Remember, this is parameter, not query string. For getting the parameters from URL, we need to use use Perms. SperaMsHok from react router dom, and this will return object of all parameters, so we can destructure it and get here ID. The reason we are getting this ID here is because in our routing, we define product, column ID. Sorry, we bimstakally add this ID one in this path. We can change this to call on ID. And if you pass here, call on product ID, then you need to destructure product ID. Save this and back to single product component. Now let's call our API by using use data hook for endpoint, we pass backticks, slash products, slash dollar Ci Brackets ID. Now, this will return couple of properties. Destructure it and here we get our data and we rename it to product. Also, we get error and ease loading. Now let's move these use params below our use state. Good. And let's remove this product object which we created but just temo. Now in our JSX, we need to add condition. So see like this all due and add here condition product is not null, only then display these due here we are getting compilation error because we are returning multiple elements. So we wrap this due with react fragments. Save the changes and take a look, select any product and see here we are getting this data, but not images. So let's display our images. We already done that in products card. So in the source, we pass ties, and before this image, we add STTP column, double forward slash, local host, Column 5,000, slash products, slash Image with dollar and curly brackets. Now, same we do here. Baptis and before this, we add STDP column, double forward slash, local host, column 5,000, slash products, slash selected image with dollar and cul brackets. Save the changes and take a look. See, we are getting our images. Perfect. Now let's handle error and loading. So for error, we adhere condition. If error is available, then we display emphasis tag and give it a class name from error, and we simply pass here error. Now for loading, we display loading spinner. So I open our previous routing project. In source folder, we have components, and in that we have common folder. And here, we have loader component. Select the both JSX and CSS piles and rub them in our common folder. Now in our component, here we add condition. If this loading is true, we add loader component. Save the changes and take a look, refresh the page and see here we are getting our loader. Now last task, when we click on this plus button, we need to increase this quantity. For that, at the top, we create a new state variable called quantity and set quantity, and by default, we pass one. Now we have to pass this state variable to our quantity input component because in that component, we have plus minus button and also count of quantity. So here we pass quantity to quantity, set quantity to set quantity, and stock to product dot SOC. Save the hinges, and let's handle them. So in our quantity input component in the props, we get quantity, set quantity, and stock. Now, here in our button, we simply add on click event, arrow function, and here we set quantity to quantity minus one. Now same, we pass for plus button. Copy this click event and paste it for plus button at the place of minus one, we add plus one, and at last, we change this one to this quantity state. Save changes and take a. C, quantity are increasing, but we have to add condition for this disable attribute. So disable equals to quantity, less or equals to one. And also in plus button, we pass disable attribute equals to quantity greater or equals to stock. Save the changes and take a look. See, when we have more than one quantity, then minus button is not disable. And if we increase quantity to stock, then our plus button is disable. Perfect. Here, our 12th section is completed. I hope you learn a lot from this. If you have some doubts, then you can ask me in the Q&A section. In the next section, you will see the most important thing of any big project, which is user authentication and authorization. If you're watching these course continuously, then I highly recommend you to take 20 to 30 minutes break from screen and get some fresh air because taking care of our health is also important. I will see you in the next section. 142. Section 13 Authentication & Authorization: In this section, we are going to learn authentication and react application, like handling signup, login and logout. After that, we will see how can we handle authorization, like only log in user can add items to the card, viewer card, et cetera. Authentication and authorization, both are very important topics for any big application. So for authentication, we are going to use JSON Web token, I'm very excited about this section and hope you are too. So let's dive into this. 143. Register a new user API: First of all, let's see register API for our user. So for tasting API, we have two options. We can use Postman, which is the external application, specially designed for tasting any kind of APIs, or we can use VS code extension called Thunder client, which has almost same features. So for simplicity, I'm going to use VSCode extension, but you can use Postman also. It's entirely up to you. Open up extension panel from here and search Thunder client. And install this extension. Good. Now let's open this tender client extension. And here we can see this type of interface. Don't worry about it, click on New request. And at the right side, we can see we have input box by API URL and also drop down for selecting STTP methods. So select post method, and the API URL, write STTP column double forward slash local host, Column 5,000 slash API slash user slash signup. Now, as we know for register, a new user, we need to send user data in the body of our API request. So for that, we simply select here body, and in that, here we can pass our data in JCN format. So first, we pass name to code. Next, email to code one@gmail.com. Then password to, let's say, one, two, three, 45678 and delivery address this is my delivery address. For now we are not sending our profile image because if we don't select our profile image, then by default, it will set to default dot JPG. Now simplically consent. And see here we get status code to 201, which is for successfully created. And also in the response, we get object with long token. This is the JSON Web token or JWT, which almost all modern application use for authenticate user. Don't worry about that. I will explain to you JCN WebTken in details in upcoming lesson. For now we are successfully registered user. We can verify that by Mongo DbCompass open user's collection and see here we get our user. Now let's see how we can send image with our API request. So for sending any files like images, audio, video, anything, we have to use Form data, which is another way to send data with our API request because in JSON format, we can't send our file. So instead of selecting JSON from here, we can select Form. Now here we can see Form fill inputs, and at the right side, we can enable files and see here we get files option. Now in the form fields, we add name and value to code plus. Email to code two@gmail.com. Then password to 12345678 and delivery address this is new delivery address. Now let's select profile image. So for fill name, we pass Profile P with capital P, and here we can choose file. So here, I'm selecting my channels logo. Now let's send a data. See, here we get new tooken, and that means our user is successfully registered. Open up Mongoibcmpass and refresh the documents. And here we can see we get new user with email code@gmail.com. And profile to some profile peak name. It's working. Now from here at the bottom, we can rename our API name. Let's say signup API. Good. Now in the next lesson, we will connect our signup form with our signup API. 144. Connecting Signup Page with API: Now here in our signup page in submit function, currently we are just console dot log these form values. Now let's connect our signup page with our signup API. So instead of writing all logic here, I would prefer to write logic in different JavaScript file. So in our source folder, we create one more folder called services. And inside it, we create a new file called user services dot js. Can you tell me why I use the dot js extension? Right, because we are not returning any JSX elements from here. Now, inside this, first of all, we input API client from here we go one folder up, utils, API client. Now here we create one function called sign up or register, whatever you want to call. And here we are getting first user object, which is the form fields of our signup form, and after that, we will pass our profile, which is profile image. Now, as we know, for sending any file, we need to send our data in form data format. So for that, here we create one variable called body equals to new form data. Now here we need to simply add all data in this body form data. So body dot up and inside this function at the first parameter, we will define name of our property, which is name. And at the second parameter, we will define value, which is user dot name. Now let's duplicate this line four more times, and here we change our name to email and also user dot email. Next, we have password and user dot password. Next, we have delivery address and user dot delivery address. And at last, we have profile P with P, and we pass here our profile. Note that the all fills name are depending upon your API. In your application, it might be user name at the place of this email. You have to pass here user name. Don't worry about that. Bend developer will give you these details about calling API because by these names in backend, we can access these values. These names are entirely depends on your back end. Now at the end, we will call our API, so api client dot post, and here we pass our API, which is sssers signup. After that, we'll simply pass our body data. When we call this signup function, this form data will generate it first, and we will send it to our back end. This expression returns a promise. We can simply return promise from here. Now to use this signup function in our form, we have to export this function from here. Save this file, and in our signup page component here in the on submit method, instead of console dot log, we simply call Signup function and you can see autoiput works. Now at the first parameter, we have to pass our form fields, which is this form data. And after that, at the second parameter, we will pass profile Peak. Now let's wrap this function in code block. Good. Now, this expression returns a promise. So we will use here Await. And for using Await, we have to add here async, simple as that. Now let's remove this console from here. We don't want that. Save the changes and take a look. Open up developer tools for Windows users, press Ftwel or Option plus Command plus I in Mac. Open Network Stab fill the form with name, email, password, confirm password, and delivery address. And click on Submit. Nothing happens, but in our Networks tab, we can see here we get one API request, which is sign up, and in the response, we are getting token. Now SelagPfile Image, and we will change this email to code four@gmail.com. Otherwise, we get error. Also, we change this name to code four and in address, we change fourth delivery address. Click on submit and see here we get again token in response. With image or without image, both scenarios are working. You can see how simple it is to send image to server in react. Just we have to make form data object and append our data in it. Now, if we again click on submit, then we are getting error message in response. In the next lesson, we will see how we can handle errors returning by signup API. 145. Handling Errors for Signup: Now, in order to handle error, we can use try and catch block. So here, we only write tryCatch and select this suggestion and see, we get try and catch Block. Now, let's place the sino function in Tri block, and in cache Block, here we get error object. So here we are only displaying error, which we return from our back end. And for that, we have to put here condition if we have error dot response and error dot response dot status is equals to 400, which means we as a client, did something wrong. So here we simply Consol dot log dot response object. Also, the reason I use tricach and acad is just to show you demo. You can also use dot Dan and cache method, which we seen in calling an API section. Save the changes and take a look, fill the form, and for email address, we pass old email and submit the form. And in the console, we can see response object. And inside this, we get status to 400, and in data, we have message to email is already registered. Now let's display this error on our form. So for displaying this error, we have to first store it in state variable. So at the top, we create State variable called form error, and set form error. As default value, we set empty string. Good. Now here we set form error to error dot response dot data dot Message. This response object is entirely depends on your backend. In your case, you have data dot error, so you have to set that inform error. Now at the bottom, before our submit button, we add here condition. If form error is available, then we return emphasis tag with class name form error and add here form error. Say the changes and take a look, fill the form and submit it and see here we get our error message. Currently, when we are submitting the form, we are only calling signup API. But in real world, we have to log in user. For now, don't worry about that. We will do that in future. 146. Login a user API: Now, let's see login API. So in our tender client extension, we add new API request. For login also, we pass here URL, STDP, Colm double forward slash Local host, Column 5,000 slash API slash user slash Login, and also select Post method. Now for this API, we are going to send data in JSON format because we are not sending here any images or files. Otherwise, we need to send form data. Now in the body, se like JSON, and here we pass two properties. First one is email, which is code one@gmail.com. And then we will pass our password to 12345678 and send a request. See, here we are getting JCN web token in our response object, and by this token, we will get log in user. For now, don't worry about that. First, we will connect our login form with this login API. So here is a little exercise for you. I want you to connect our login form with this login API and also try to handle errors. And if it is server error, display it before login button. Same as we done for signup form. This will hardly takes two to 5 minutes, give it a try and then was the solution. 147. Connecting Login Page with API: So I hope you solve this exercise. Now let's see the solution. So as we create our signup function in user Services file, we will add new function for login. So function, login, and here we get user data, which we send from login form. And here, we simply return this api client dot post. Here we pass our path slash user slash Login. And at second parameter, we simply pass this user object. Now to call this function in our login form, we have to export this function. Save this file and open login page component, and in submit function at the place of this console dot log, we pass login function from user services and simply pass here our form data. Now this expression returns a promise, so we await for that and for using await, we need to add here async. Save the changes and take a look, open up Login page and enter our email and password eight Enter and nothing happens. But in Network Sab we can see the API call, which return JWT token in the response. So our half task is done. Now we have to only handle form error. So back to VS code, and here we add try and catch block for handling error. Move this line in try block and also in catch method, which in this error to error object. Now inside this catch block, we add the same condition which we added for signup form. So on signup form copy this I condition and simply paste it in our login form. For using set form error, we have to create that state variable. At the top, we create state variable called form error, set form error, and as default value, we pass here empty string. Now at last, we simply saw this error on our form. Before our submit button, we add condition. I form error is available, then sew emphasis tag with class name, form error, and simply pass here form error. Save the changes and take a look, fill the form with wrong details and submit the form. See here we are getting this error. 148. What is JWT & How it works: Now, before we go deeper into user authentication, which we do by using JCN Web token or JWT. Let's first understand what is JWT. So JWT stands for JCN Web token, which is used to securely transfer information between two parties like Bend and front end. Let's understand this with the example. So here is a Harley. He log in with his account information, email and password. Our server first check the information and if it's true, then server returns its user ID as response and store that in session or Cookie. Now, whenever he's in request for some secure information, let's say all his bank information. Server first ask for the user ID and if he has user ID, then and then server sends the secure information. But here is a one big problem. This session or cookie in which we store our user ID, it can be easily modified in the browser. Let's say I change this user ID to someone else user ID. Then we get the information about data user. So this approach is not secured. Now to solve this issue, we introduce JSON Web Token. So now Halley again log in with his email and password. Now our server first check the information, and if it is true, then server returns the long encrypted unique token as response and store that in the local storage. Now, the great thing about this token is it made with user details and one secret key, which we define on server. So whenever Harley sends request for secured information, then server first ask for JWT token and verify it using our secret key. It's verify, then then server will send that secure information. If we change anything in user information, then our token will change. I know this is a little confusing. Let me show you practically. In our testing API, we copy this JSON web token. In our browser, open a new tab and search jwt dotiO. This is the official documentation of JWT. Here in the libraries, you can see JWT implementation for different different libraries. Now scroll down to the Debugger section. Here we can decode our token. So let's understand what token contains. So paste our token here. Now all GWT tokens divided into three parts. First part is about header, which is in the red color. Second part is about payload, which is in the purple, and last and most important part is signature, which is in the blue color. Now this header contains the algorithm and token type, which is very common. Don't focus on that. Now this payload contains the data, which server send with our token. In this case, I pass this user's data. We can set at the back end which data we want to send in this payload. So we can display that data on our front end without calling separate API, and we have more data I At which stands for issued at, and the value is time when our token generated, and EXP is our expiration time. Now the last part which is in the blue is signature, which is generated based on this header, this payload data, and secret key, which is only available on server. So this will prevent users from getting their own token and then modify it with ID to pretend to be someone else. Because if you modify anything in this payload or header, then this signature will regenerated. So there are no chance for user to do something unethical. So that's why JWT is so popular. Now let me show you what is secret key. This secret key is a string which we define at the back end. So in our back end, we have this dot ENV file, and here we define JWT secret. I know this is easy password, but I just set it to show you. So by only this secret key, our token will validate. Otherwise, it will give us error. So to sum up, when users successfully login or register, we get JSON web token which simply work as security card. User request for data, which is only accessible by log in users, then server first check the security card, which is our JSON web token and validate it with the JWT secret key. And if that token verified, only then server returns that data to our user. Simple as that. 149. Storing the JWT after Login & Signup: Now, as we know, if it's a register or logged in with valid email and password, we get JSON Web Token in our response. So we have to store that token on clients site. Now you might think where we store that token. Remember, we have done that in our task wreck project. We store our task in the local storage, which is the little storage of browser. Here we are waiting for our login API, which will return response object. So let's store that in variable called response and simply console dot log this response. Save the changes and take a look. Fill the valid email and password. And submit the form. See, here we get response object, and here in the data, we get our token. Now, let's store this in our local storage. So at the place of this response, we can destructure that and get here data. Now remove this console, and we write local storage dot set item. This method takes two parameters. First, our variable name, which is token and second, the value of the variable, which is data dot token. Save the changes, and again, login with valid email and password. And let's see we get token in local storage or not. So open up application tab from here, and in our port, which is Local host 5173. Here we get our token. Now the last thing we need to do is to redirect user to the homepage after login. So here we call use Navigate Hook from a Crouterdm and store it in constant Navigate. Now we simply use here, Navigate, and pass here homepage. Save the changes and take a look. Fill the form with valid details and submit it. See, redirect to homepage. A login form is working properly. Now we will do the same when user register on our website because I don't want user have to login again with the email and password after they just registered. From here, we copy these two lines and in our signup page component, after the await, we page those lines. Now let's store this API response in constant and destructure it and get here data. And at last, we have to define this navigate. So after our use state, we call use Navigate Hook and store that in constant, call Navigate. Save the changes and take a look. Go to the signup page, fill the form with name, email ID, password, confirm password, and delivery address. And we click consubmit. See, we again redirect to homepage. So this is also working. 150. Getting User from Token: So in the previous lesson, we successfully store our JSON web token in local storage. Now, do you remember when we decode our token on JWT website, we get current user data in the payload. So we need to decode that user data from the token and store it in the state. But the main question is where we will define that user state, where we need that user object. We simply need user object in all our application. In the app component, we will define our user state because app component is our root component, and from here, we can pass user object in all our components as props. At the top, we had used it hook. First, we import it, and then we add used it snippets and pass here user and set user. As the default value, we pass null. When our component gets rendered, we need to decode our JSON web token and store that data in this user state. And for that, what we will use, right, we use use effect Hook, so call use effect. At the first position, we pass callback function, and at the second, we pass empty array because we only need to decode our token once. Now in this callback function, first, we will get token from local storage. Sit local storage dot got m, and here we pass our variable name, which is token. Now let's store this invariable, called token or JWT, whatever you want to call it. Now to decode this ZSN webTken, we have one library called JWT decode. So open up terminal, we write NPM install JWT decode and hit Enter. God. Let's minimize this terminal, and at the top, we import JWT decode from JWT decode. And in our use effect, we call this JWT decode function and pass here our JWT. Now, this will return user object. Store it in variable JWT user because we already use user here, and we simply consult dot log this JWT user. Save the changes and take a look. Refresh the page, and in Console, see, here we get our user object. Let's simply store that in our user state variable. So at the place of console dot log, we add set user. Now we can pass this user object to Nabar component as a props. But before we do that, let's check one condition. What if we don't have token in our local storage? So in our browser application tab, select this token and remove it from here. Now refresh the page and in Console, C, we get error, which is invalid token specified. So when we don't have token in the local storage, we get nothing in this JWT variable and then that null value pass to the JWT D code, and this is giving us error. So to fix this issue, we adhere try and catch block and simply move this code in the Try block. So if we have error in this code, we simply do nothing. If your application only works for log in user, then in this sketch method, we can redirect user to log in or register page. But for our application, that's not the case. Save the changes and take a look. Refresh the page and see, even if we don't have token, we don't get any error. Now here is one more thing. Almost every time Backend developer set an expiration time for our JSN web token for security reasons and the time we get in our decoded value. In this Bend, I set expiration time to 1 hour, which means after 1 hour or token is not valid and that will also give us error. In our use effect, after we store this decoded value in JWT user, we pass here one condition if date dot now. Is greater or equals to JWTuser dot EXP, multiply by 1,000. If this condition is true, then our token is not valid. So here, we can simply remove token from our local storage. So local storage, dot remove item, and pass here Tgon. And after that, we simply reload our page. So add location dot reload. Now we pass, which means our token is valid. Only then we set user to JWT. Simple as that. Now you might ask why we here multiply by 1,000. So this date dot now function return the current time in milliseconds. So to convert this expiration time in milliseconds, we have to multiply it with 1,000. See the changes, and it will work for us. 151. Hide Show Component depending upon User: Now we have user object, which indicates user is authenticate. So by that object, we can show or hide components. Here in the Navbar, we only want to show these Moders logout and cat links if user is logged in. So here, in the NaBr component, we pass this user as the props. Save this and in Nabar component, we get a user props here. Now at the bottom, we wrap these three links with the curly brackets, and here we simply add condition. If user is available, only then show these links, but this will give us compilation error. So we have to wrap these links with react fragments. Now same we have to do with these login and sign up links because if user is already logged in, then we don't need login or signup page. So wrap these with Cy brackets, and here we add I user is not available, only then display these two links. And again, we have to add here react fragments now if we want to display here user name, we can also do that by using this user object, save the changes and take a look. See, currently we don't have user object, and that's why we get here login and sign up links. Let's check this. In the developer tools, open application tab and see here we don't have token. Now, let's open Login page and login with valid email and password. And click on submit and see here we get our token. But still, we get login and sign up links, even we have user state. Why is this happening? Simply because in the app component, this use effect will only run one time when our app component gets render. So when we log in our form, our app component is already render and it's already stored user to null. Let me show you something cool. The moment we refresh this page, we can see here we get our log in links. To solve this issue, we only need to refresh our page on login. Open up login page component and at the place of this navigate, we simply write window dot location equals to in double codes, we pass our home page. Now let's remove this navigate variable and also at the top, remove this use navigate input. Save the changes and take a look. Remove this token from local storage, refresh the page, and in the login page, log in with email and password and submit. See, our page get refreshed and we also get logged in links. Now let's do the same with signup page. So open up signup page component, and at the place of this navigate, we write window dot location equals to home page. Now remove this navigate variable, and also at the top, we remove use Navigate Import, and we are done with this. Now in the next lesson, we will implement logout functionality. And 152. Implementing Logout Functionality: Now currently for log In Out, we are manually removing token from our local storage. But in our application, we have our logout link, which we can use for implement logout functionality. So when our logout component will render, we will remove this token from local storage. So for that, in the routing component at the bottom, we add one more route and we set path to slice logout and element. Here, we need to create a new component for logout. In the component folder, we have authentication folder, and in that folder, we create a component called logout. Now let's add boilerplate code. Also, we remove this due, and we will return null because we don't want to render anything. Now to run code at the component render, we have to use use effect Hook. So here we add use effect, callback function, and as dependency, we pass empty array. Now let's write our logic inside this callback function. Local storage dot remove m, and here we pass our variable name, which is token. Save the changes. And in our routing component, here we add logout component in the element props. Save the changes and take a look. Click on Logout Link and we get here nothing. But if we check our local storage, we can see that Token is removed from here. Now we have to redirect user to our homepage. So for that, what we use, right, we use window dot location. So in the logout component, we add here window dot location equals to homepage. Save the changes and take a look. Login into our application with email and password. And see we logged in. Now, click on Logout and see it's working. So now our application has login and logout both features. So that's how we will implement login and logout functionality. You can see how simple it is. When developers don't understand JWT only then they found this complicated. 153. Simplify the code: Now in our current implementation, there is little problem. So here, after login, we are working with local storage and setting this token in it. Same we have done in the signup page. C. Also in the app component, we are getting that token from local storage, and in the lockout component, we are removing that token. Tomorrow, if we decide to change this token name to something else, then we have to update that name in the multiple components. So it's better to put this all logic in single place. So in our user services file, in the login function, we are only returning the promise of our API. Instead of that, we can also save our token in this function. Let me show you. So at the place of return, we add await and for adding await, we have to make this function async. Now we can save this response in constant and destructure data here. And at last, we add local storage dot set item to token and pass here, data dot token. So this login function, taking the complete care of our log in logic. Save this and in our login component, we remove this constant, and also we don't want this local storage dot set item. Now you might ask why we don't move this redirect in our login function. So after successfully login, where users should redirect is not the scope of that login function. It's entirely depends on this login function. Tomorrow, we decide to redirect user to different location, then we don't need to change that login function. Save this. Now let's close this login page component, and let's do the same for our sign up logic. So let's cut this local storage dot set item, and also remove this constant. Save the changes, and in the user services file at the place of this return, we add await and store that in constant and restructured data. And after that, we simply paste this local storage line, and at the end for await, we make this function async. Good. Now let's simplify Logout feature. Sc at this local storage dot remove IM function. And in our user services at the bottom, we create one more function called Logout, and simply paste here, remove item line and export this function from this file. Save this and in our logout component, we simply call this Logout function. Save this file. Now we have to update last piece of code, which is in the app component. So in our user services file, we create another function called Guser and in this function, first, we get token from local storage. So Const JWT equals to local storage dot get item. And here we pass token. After that, we decode our JWT token. At the top, we import JWT decode from JWT decode. After that, in our function, we call here JWT decode and pass here this JWT. Now this returns our user object. So we return that object from here. But what if we don't found this token in the local storage? For that, we have try and catch block in our app component. But in other places, if we call this Get user function, then we will get error. So we add here, try and catch block. And move these lines in the tri blog. And if we get any error, we simply return here null, simple as that. Now, let's export this get user function, save this, and in our app component, remove this first line, and at the place of this JWT decode, we call Gatuser function. And at the top, let's remove this JWT input. Save the changes and back to our user services file. Now, if we want to change our token variable name, then we have to only change that in this file. Now we can even store that variable name in variable. At the top, we create variable called token name, and we set it in double codes token. Now in the sign of function, select this token string and press Control plus D or Command plus D for multiple cursor and replace it with token name variable. Now we have to only change this name at the single place and see our code looks more clean and maintainable. Now in the next section, we will see how we can call protected APIs, and by that, we will almost complete this project. S in the next section. 154. Section 14 Calling Protected APIs & Routes: Welcome to the 14 section of the ultimate react course. In this section, we are going to see how we can call protected APIs, which simply means some of our APIs are only for adjusted users. Like on our My Order page, we need to get all order details of current log in user. So we will see how we can call protected APIs, and if user is not logged in, we will simply redirect user to the login page. And also, we will see how we can manage protected routes. I'm really excited about this section and hope you are too. So let's get started. 155. Understanding Add to Cart Feature: Now, before we implement head to cart feature in our application, let's understand this feature deeply. So first of all, we have head to cart button into components. First one is on the product card and second one on the single product page. So for cart, we create one State variable, which will store the products, which we added to our card with the quantity. Example, if we have Iphone 14, we can select the quantity of that product, and then we will click on head to Cart button, and our Iphone 14 will added in our cart array with that quantity. So for each product, we have new object with two property, product, which is the product object, and we have quantity, which is the current selected quantity. In this cart array, we can have multiple products, and we show the cart size in our Nav bar. This is the part one. Part two is our card is a local variable, which means if we refresh the page, this card will be empty again. We don't want it, right? So what is the solution here? So after adding these card details in the state, we can store user card details in the back end. And on refresh, we will get that card details from the back end. If we get error in adding products to card, then we will restore our card in the previous state. Simple as that. We already done that in our calling a PI section. First, we will see how we can store our card details in the local state. 156. Add To Cart Locally: Let's start with our first step, which is adding products in the local state. So first step to add any state variable is we need to decide where we create our state variable. So here is a componentry of our application. We have app component as the root component. Inside it, we have two components Nabar and routing. And inside this routing, we have single product page component, and inside this, we have our head to card button. We need array in two components, Na bar and single product page. Now, let me give you a shortcut for decide where we define our state variable. If our state variable is needed to access in two different components, then we should define that state variable in the closest parent component. In simple words, just see which parent component is closest to both NaBr and single product component. So here, closest parent component is our app component. And if we define cart in a component, only then we can pass that cart state as props in these both components. So in our app component, after this user state, we add one more state variable called cart and set cart. And as the default value, what we will pass right, empty array. Now, first of all, what we need in the NBR component. We only need to display the number of products in our current card. So as the props, we pass card count equals to cart dot length. Save this, and in the NBA component, we get card count in the props and at the bottom, at the place of this zero, we simply display this card count. Say this and now we don't need to worry about this Navar. Now back to a component here at the place of passing card and side card in the single product component, we can create one function here, const head to cart, arrow function, and inside it, we write our logic for adding item in the cart array. Here in the function parameter, we get the selected product, and also we get here quantity of that product, which is the number of products we need to add. Here, we simply set card to array. First, we add all previous card values, and after that, we add new object, and here we set product to this product and quantity to this quantity. Or we can simplify this code by removing these both. If you are later confused by this syntax, then don't worry, you can use that old syntax. It totally depends on you. Now, let's pass this head to card function through props. So in the routing component, we pass at to card to head to card. Save this file, and in the routing component, we get here at to card function in the props. And again, pass it in the single product page component. So head to cart equals to head to cart. Save this file, and in our single product page component, finally, we get here head to cart in the props. And at the bottom, in our head to cart button, we pass on click event, and in that we add arrow function, and here we call head to cart function. And as the first argument, we pass our product object, which we are getting from back end. Look, and as the second argument, we pass quantity. See the changes, and take a look. First of all, open developer tools, open any product page. And from here, we can change the quantity and click on Ed to Cart button. And see at the top, we get counter to one. Now, let's open another product page and click on Add to Cart button. And here we can see the counts updated. Now, let's see our cart array. So from here, we open Components tab and select our app component. Here we can see cart array. Now change the same product quantity and click on at two card. See, here we get three products, and that's the bug. So we have to fix this. So in our app component, we remove this set card function and we will write the logic from scratch. So first of all, we create a new variable called updated card and add all previous value hereby using spread operator. Now we find a selective product index in this array. So updated card dot find Index. Here we get each item and check here condition to m dot product dot underscore ID equals to product, dot underscore ID. And we store this index in the variable call product index. Now this find index method return the index value of the product. And if our selected product is not available in this array, it will return minus one. So here, we have to pass condition if this product index equals to minus one, which means product is not in our cart. Then we call updated cart dot push method. And here we push object with product to the product object. Quantity to this quantity. Else, we will only update quantity of the added product, Ste updated cart. Here we pass product index dot quantity plus equals to this quantity. If product is not available, then we add new object with product and quantity property. Otherwise, we addition the quantity with old quantity of their product. Now at the end, we simply set cart to our updated card. Save the changes and take a look, refresh the page, add one item, and click on ad to cart. See it's added. Now change the quantity, and again, click on ad to cart. See here, only quantity updates. 157. Calling Protected API: So in the previous lesson, we store our products in the local card state. Now we will see how we call this head to card API. Now you might ask why I am putting so much weight on calling this API? Is that the same API like fetching products or getting categories? And the answer is no, it is not the same API as we call previously. This is the API which can only access by the log in users. Let me show you. So Tender client panel and here we add new request, select here post request, and write API to SDTP column, double forward slash, local host, Column 5,000 slash API, slash CAT here we pass our product ID. For now, just pass here random ID, and we have to pass number of quantity in the body of this request. So select body, and here in the JSON, we just pass quantity to five. And send the request. Here we can see we get error, access denied, no token provided. Now let me show you how we are getting this error from backend. In the Bend project, we have this routes folder, and in that we have CAT file in which I define all CAT API. Now in the line 27, we have to cut route, and here I add oth metal ware. Don't worry. If you don't know node jazz, I'm just telling you how we are getting this error. You don't need to code single line in the back end. So this oath is a middleware which runs first before our main API code will run. Now let's see what is inside this oth. So in the middleware folder, we have oth middleware, and here we have this function. First, this function will get our JSON web token from our request header named X a token. And then if we don't pass our JSON web token in this header, it will give us this access denied error which status code 401. And if we have token and that token is verified by JWT secret key, then it will run our API mean logic, such as the overview of this oth middleware. In short, for accessing protected APIs, we have to pass our JSN web token in our header XTken. Only then we can access protected APIs. Almost all applications somehow pass token to the back end and most common and secure way is by header. In our application, we also need to set our JSN web token in the X or token. So for passing token in header in our Utils folder, we create one more file called set autocon dot js. Now, in this file at the top, we import API client from this API client file, which is our ready made axios variable. After that, we define const set token function. And in the parameter, we get our token arrow function, and inside this function, we add one condition. If token is available, then we will set API client dot defaults, dot headers dot common, square brackets, and here we pass our header name, which is X or token. We define the same header name in the back end. In your application, it might be different. So you have to pass that name here equals to, we pass token. Now in L, we will remove this header, delete, copy this expression, and paste it here. And at the end, we simply export default this set or token function. Save this file, and now in our app component outside of this function, we call the set or token function. And here we need to pass our JSON web token, which can be stored in local storage. So we can write here local storage dot get item, and token. Now, as we know, we are defining all our local storage tokens in the user services file. So instead of writing this local storage here, we can cut it and in the user services file at the bottom, we export a new function called Get JWT. And inside this, we simply return local storage dot get item, and here we pass token name. Save this file, and in our app component, we can call here Gt JWT function. Simple as that. Now for our application, we don't need to send our token header in each single request. We set that for all our API calls. 158. Calling Add to Cart API: Now let's call our head to card API. In the services folder, we create a new file, call card services in which we will define all APIs for our card. Same as we done for user services. By using this way, we can easily maintain our API calls and we don't need to write same API call multiple times in our application. So at the top, we import API client from Utils slash API client. Now create a new function called Add to Cart API. And inside this function, we will call our API. So api client dot post. Here in the backticks, we add slash CRTs now here, we need to add our selected product ID, so we can get that product ID as the parameter of this function, and we need quantity of that product. Now in our API, we pass Dollar calibracets ID. And at the second parameter, we will pass our body object. And in that, we set quantity to quantity or we can remove this. This expression returns the promise. So we can simply return this promise from here. A, let's export this function from here, save the changes, and in our app component in the head to cut function, after we update our local state, we call head to cut API function from card services. And here we need to pass two arguments. First one is current product ID, which is product dot underscore ID, and second one is the quantity of this product. Now as we know, this function will return promise. We can handle that using then and cache method, or we can use try and catch also. But I personally like to use then and catch method. Dot then now what we will do if we successfully added product to CAT. Here we can simply display alert or we can show toast notification. So for now, we simply const dot log, this response dot data. And in the cache method, we have to handle error. For now, we simply console dot log this error dot response. And also, if product does not add in our card, then we will restore our card state to previous state. Simply set card to card. Save the changes and take a look. Open up Console, change the quantity, and Glicon to cart and see we get here message, item added to card. Now let's check that in our database. So in the Mongo D become pass, open card collection. See, here we get one document, and in that we have our product. Perfect. Now let's simply show toast notification for success and error. Now you might ask what is toast notification? Let me show you in just a minute. First of all, open up terminal, and in the new terminal, we write NPM, I, react, dessify and hit Enter. Using React to Stify Library, we can display our notifications very easily and modern way. Now minimize this terminal, and at the top, we will import toast container and also toast method from react to Stifi Library. And also, we have to import its CSS file for adding styles. So import, reacts tostify dis react, Tostifyt CSS file. Now we need to add this toast container component in our application, so we can add it anywhere in this tube. So here we add toast container component. Now we just need to add our message in that toast function. So in our then method, at the place of this console, we add toast. Now here, we can select multiple methods. For example, we have success which will show notification in green text. And here we pass our message product, added successfully. Now let me show you other methods as well. So duplicate this line four more times and change this method to error for red color, warning for yellow warning, info for blue color, and also we have default. For that, we won't pass anything. Also, in the catch method, we add toast dot error and message to failed to add product. Save the ginges and take a look. Click on at to cart and see here at the top right corner, we get our toast notifications. If we are our cursor on notification, it will stop there. So this is the toast notifications. You can see how simply and easily we can add notifications. Now at the place of displaying toast notifications at the top right corner, I want to show them in the bottom right corner. In the toast container component, we have one probe called position. If you don't get autoizon, then press Control plus space or Command plus space and see here we get couple of properties. Here we select bottom right. Also, we can more customize this toast notification. For that, you can refer its official documentation. They explain it in very simple and easy language. Also from here, we remove these unwanted toast notifications. O 159. Fetching User Cart From Backend: So currently, when we are adding products to our card, it is successfully added in our database. Now, on our card page, we have to only display card details in our table. So when a card services file, and here we define a new function called Get card API. And in this function, we simply call api client dot GAT. And for getting the card of user, we pass SCAT. You can use our API documentation for the reference. Now, this expression returns a promise. So we return this, and let's export this function. Save this file, and in our app component, after this head to card function, we create a new function called Get card. And inside this function, we simply call our Get card API. Now, what will this function written? Right, we get here, promise. Dot then, here we get response and we simply set cart to the response dot data. In the catch method, we add toast dot error something went wrong. Now on which page we want to fetch card API. You might say on the card page, and that's the wrong answer. Let me show you what will happen if we call our Gecard function in cart page. In routing component, we pass Get card props to G cart. Save this and inside the routing component, first of all, we get here the props and pass it directly in the card page component. Get card to G card. Save this and in the cart page component, we get our Gcard function in the props, and in the use effect, we will call this function. So use effect and pass Callback function, and Empty array as the dependency. And in the callback function, we simply call Get card function. Say the changes and take a look. Here we get error. So let's see this in Console. Here we get getcardpi dot n is not the function. In our app component, here, I forgot to call this function, save the changes and take a look. See, our error is gone, and in our component tab, select app component, and here we get card array. Now, if we refresh the page, then we are also getting the card details. Now let me show you main bug. Go to the products page and refresh the page. Currently, we have zero items in our cart, but in the back end, we have two items. If we had that same item, then in the cart local state, we have new product with new quantity. But in the back end, we have another quantity. Basically, if we call Get card only on cart page, then our back end card data and cart local state will have different data and we don't want that. So we can call this Get card function in the app component. So in our app component, we add another use effect, and here in the callback, we call our Get card function. But here, we have to pass on condition. If user is available, only then we will call this Get card function because this API is only accessible by log in users. And in the dependency array, we can add here user. When user change, this Get card API will run. Save the changes and take a look, refresh the page and see in the card, we are getting our card details. Now, one question you might ask why we don't remove Getcard function from the card page component. So we can use it as a double check for our card details. If you want to remove this use effect, you can do that as well. It's totally fine. Let me also remove this. Now, we just need to display our card details in this table. So for display card details, we need card state in this component. So back to our app component. At the place of these cat card props, we add card to card. And in the routing component, we also change this cart and pass here cart to cart. And at last, in our CAT page, here we get our CAT array. Now for verify, we console dot log this CAT array, save the changes, and in the CAT page, open up console refresh the page and see, here we are getting CAT array, which is the array of object with product and quantity property. So in our cart component at the bottom, in the Te body, we add cart dot map. Here we get single item, arrow function, and here we simply return this table row. Now here, this item is an object, so we can destructure it and get here product and quantity properties. I am going a little bit faster because we are working on react from many time, and you already knew these things. If I explain you each step, you will definitely gets bored. So first, in the table row, we add key attribute to product dot underscore ID. Next, we replace this name with product dot title. Then we add product dot price. Next, we have quantity input. So here we pass quantity to this quantity and stock to product dot stock. For now, we use set quantity function. And in the total, we pass quantity into product dot Price. Save the changes and take a look. See, in the table, we get our items. Beautiful. Now let's calculate this subtotal. So for that, at the top, we create a new state variable, so select uste and select the snippets, give it a name, subtotal, and set subtotal and default value to zero. Now for counting the subtotal, we use use effect, pass here, callback function, and in the dependency array, we add cart array. Can you tell me why we use here use effect? Right. Because when we change our cart data, then also we want to see the updated subtotal. So in the callback function, first we define total equals to zero. Then we use cart dot for H loop. And here we get each item arrow function. And here we do total plus equals to item dot product, dot price into item quantity. And at last, we simply set subtotal to this total. Now at the bottom, here we pass subtotal and in the final total, we write subtotal plus the zipping charge, which is five. Save the changes and take a look. See, here we get our subtotal and total according to our card data. 160. useContext hook: So currently in our application, we have user state and card state in our app component. Now, as in our card component, we need to display these user details and profile at the top. One solution is, we will pass our user object using props through routing component and then in the card component. We have done it so many times with this card state, but that is really waste of time and that also called a prop drilling, which means we are drilling all components for passing just one props to the child component. Another way to pass data is using use Context hook. So use Contact hook is used to manage global data in react application like theme, user, card details, et cetera. In simple words, by using use Context hook, we can make our data globally access by any component. So if we make our user data global, it can be accessible in any component which we want without manually passing through props. Let's see how to create contexts. So to create context in react, we need to do three simple steps. First one, creating the context, second, providing the context, and third, consuming the contexts. Don't worry about any of them. See this and at the end, you will see the magic of contexts. So let's start with step number one, creating the context. So here we are creating the global state for our user. So in the source folder, we create one more folder called Context. And in this folder, we will define all our contacts. So here we create a new file called user Contacts dot JS. Now to create context, first, we import create context function from react library. This function is used to create context. Now we call this create context function, and here we pass null for the default value and store that in variable called user context. You can give whatever you want to, but it's better to call the same as fine name. And at the end, let's export default user context. So our first step is completed. Now let's do step number two, which is providing the context. So where we define our user state, we have to input the contexts in that component. So in the app component at the top, we import user contexts from Context, slash user contexts. Here, we need to define which components should access this user context. So again, in that hierarchy, if you want to pass user data to card component, and also we want our user data in the Navbar component. So here, we just need to provide the data to Navbar and routing components, and that data can accessible in all their child components. So wrap these both components with the user context dot provider. So whatever component you pass between this provider, it and its child components can access this context value. Now we can pass value by using value attribute in this context provider. So write value equals to, we simply add here this user. In this value attribute, we can also pass functions, objects, anything. Now let's see how to access this variable inside our cart page component. Open our card page component in which we want to use that value. But how can we access that value? So at the top, we import use Context hook from react library. And inside this functional component, we write use contexts, and it except one argument, which is our user context. So we need to import that user context from our contexts slash user context. Now pass this user context inside this use context hook and we store this value in variable called user object because we already defined user here for our image. Now let's consolate Save the changes and take a look. Here in the application, my token get expired. So I have to login again, and here we go to Card page. See here in the console, we get our user object. So whatever value you pass in this context provider, we can access that value by using use Context hook. If you understand these three steps, then congratulations. You understand the use context hook. So here at the place of this user image, we add backticks, and inside this SDDB cool double for our slash, local host, Column 5,000 slash profile, slash and here we add our profile picture name. So dollar, Cully brackets, user object, question mark dot, profile pick because if our user is null, then we get error here. Next, at the place of this name, we add name to user object, question mark dot name. And next, at the place of this email, we pass here email to user Object, mark dot email. Save the changes and take a look. See, here we get our user data without passing through props. Now here we don't need this user image, so remove this, and now we can rename this user object to user. Now back to our app component. Here we pass user as the props. We don't need to do that anymore. Remove these user props from here and in the newer component at the place of getting this user from the props. Here, we call use Context hook and inside it, we pass our user context and we store that value in user variable. Save these and see it works the same. 161. Exercise Creating Cart Context: Now it's time to little exercise. As we define our user context, we can also define cart context because we are using it in the card component page. And in that context, pass values like cart array and head to cart function. I want you to define cart context and get that cart and Ed to cart function in value and get those values in cart page component and also update all components which are using cart or head to card function from props. Know this is easy exercise and you can do that in just a two to 3 minutes. Complete the exercise and then watch the solution. I hope you solve this exercise. Now let's quickly see this solution. In the Context folder, we create a new file called card context dot gs. First stap to define contexts is we have to use Create Context function. Add here create context and see, with the help of autoiput we get that as the default value, we pass here null now store this function in variable called card context, and at the end, we simply export default this card context. Save this file and in the app component where we define our card rate, so we have to add our provider in that component. So here, after user context, we add card context, select the auto Import, dot provider, and wrap our components with card context dot provider. And inside this provider, we have value props equals to now here at the place of passing single variable, we can pass object of variables and methods. So first, pass cart array and second at to cart function. Here, this both means head to cart to add to cart. I'm directly writing SOT code. Save this, and now in our cart page component at the place of getting card array from props, we can simply addhe, use Context, and inside it, we pass card context. And we get those values here in the variable called card context. Or we can destructure that object, and here we get cart and add to card function. See the changes and take a look. See, it works the same as before. Now let's replace all card which we are getting from props. So always start with the root component app, and we can see in the Near bar, we are passing card count, which is cart dot Length. So we can remove the and in the nebar component at the place of these props, we call here, use Context and pass here, card context, and we store that value in variable and restructure that object and get here card. Now at the bottom, at the place of this cart count, we add cart dot length. Save the changes and take a look. See, it's also working. Now let's check other components. So back to app component. Here we can see cart and heat to cart both are passing through props. So remove these both props. And in the routing component, we also remove these props. And also remove this at to cart function from single product component, and also remove card props from card page component. We already updated this card page component, so don't worry about that. We just need to update this single product page component. So open that component and remove the props and we call here, use Context Hook and simply pass here, card context. This will return our values, so we destructure it here and get at to cart function. Save the changes, and you can see how simply and without doing prop drilling, we can pass our variable in the component tree. 162. Removing Items From Cart: Now, let's implement a remove item functionality. First, we will remove product from our local state. Then we will call API for removing item from our back end as well. So first, let me close all these files. And in the app component, after at to cart function, we create a new function called remove from card. And in the parameter, we get ID of product which we want to remove. So in this function, first, we will store our current CAT array in variable called old card, equals to array and spread our cart array. Now we write Old card dot filter. Here we get each item, which is the object with product and quantity property. And here we pass condition, item dot product, dot underscore ID is not equals to this ID. So this will return new array with all products whose ID is not matched with this ID. So we will store that in a new variable called new card, and after that, we will simply set card to this new card. Now, let's verify this code. So here in our card context value, we pass our remove from card function. See the changes, and now in our cart page component, we will access that function. After this card array, we remove this at to card from here. We don't need it and get here, remove from cart. Now in the bottom, we have our remove icon. In this image, we pass on click event, arrow function, and here we call remove from cart function. And simply pass here product dot underscore ID. See the changes and take a look, repress the page, and let's remove one item from here. See that item is removed from our cart array, and also our subtotal and final total is updated according to our new card. Now if we refresh the page, we have our product back because we are getting our card from database. For removing product, we have to also remove it from our back end. Open up card services file, and at the bottom, we define a new function called remove from card API. In the parameter, we get the product ID. Now inside this function, we call API client dot patch method because we are only updating part of our data. Now for API backend, we use here backticks, cart, slash remove, slash now here we need to add our product ID which we want to remove from our cart. Now we return this expression and also at the end, export dysfunction. Save this file and in our remove from card function, at the end, we call our remove from card API and pass here our product ID. Now, this expression will return a promise. Here we use then method. But if we successfully remove product from our card, then we don't want to do anything. Remove this then and we add catch method. If we have error, we will display in toast dot error and pass here something went wrong. And after that, we will set cart to old cart. Simple as that. Save the changes and take a look. Remove item, item removed from here. Also refresh the page and see it is also removed from backend. You can see by using contacts and services how easy and simple it is to call a PI. 163. Increase and decrease product quantity: Now let's implement increase and decrease feature for CAT. In our app component, after this removed from cart function, we define a new function called update cart in the parameter, we get product ID, which we want to update. Inside this function, we first declare one variable called updated card and store all previous values of our card. Note that this is updated card, not update card. After that, we write updated card, dot find Index. Here we get single item, and here we pass our condition, item dot product dot underscore ID equals to this ID. This will return the index of our selected product. Store that in the variable call product index. Now here we do something like this, updated AT and pass her product index dot quantity plus equals to one. And then we simply set cart to updated CAT. Now here is one thing. We are going to use this function for both use cases, increasing and decreasing. But here, are performing only increased logic. In our function parameter, we add one more parameter at first called type, which can be increase or decrease. After finding the index, we add condition I type equals to increase and inside this I block, we simply move over this logic. Now let's duplicate this I block and change this type to decrease and change this to minus equals to one. Now at the bottom, let's pass this function in our context value. Save the changes and the question is where we will import that function? Should we input that in quantity input component? The answer is no. Because in our single product page, we are using the same quantity input component just for changing the quantity of the product. At that place, we don't want to call API. Here is the solution. In cart page component, we get our update card function. And in the quantity input, we have set quantity props, which is the function we will call on on click event of plus minus button. I know this is a little confusing. Just see this one time and you will understand all of this. So in this set quantity, we pass our update card function, and also we pass her new props, card page to true and product ID to product dot underscore ID. Save these and in the quantity input component in the props, we get here card page and product ID. Now in this click function, we adhere condition. If cart page is true, then we will call a set quantity function. In that case, that is our update card function. So here we have to pass two arguments type and product ID. So first type to decrease and second product ID. Now if our cart page is not true, we simply do set quantity to quantity minus one. So now you understand why we add this card page and product ID in these props. Now simply copy this onclick event and paste it at the place of this onclick event. And first we change this type to increase and in L change this to quantity plus one. Save the changes and take a look. In the card page, click on the plus minus button and see our quantity is changing according to that. Also price gets updated. Our half task is done here. Now we just need to call API for increase and decrease. Where we define those APIs in the card services file. Good. You are learning really fast. I love it. Now here, we simply duplicate this removed from CAT API function two more times because those three APIs are almost same. Now let's change this function name to increase product API, and in the API endpoint at the place of this remove, we have to add increase, and that's all we have to change. Now let's do the same for decrease API. So change function name to decrease product API. And in the endpoint, we change this to cart slash decrease. Save the changes, and in the app component in our increased type blog, we call increase product API and simply pass here ID. Now we don't need then method. We directly add cache method. And inside this cache method, first we add toast dot error and pass here, something went wrong. And after that, we set cart to previous cart. But here, in this function, we don't have previous cart because we change this updated card array. So at the top, we define const old cart equals to array and spread cart array and simply pass this old cart in our SAT cart function. Now in decrease type blog, we call decrease product API and also pass here ID, and we can simply copy this catch method and paste it here. Save the changes and take a look. Change the quantity of the product, and we can verify the changes on repress. See, we get updated quantity. So here we successfully complete our at to card, remove from card, increase and decrease feature. 164. Add to Cart in Product Card: Let's call head to cart API for our product card basket icon. In the product card component, here we can use head to cart function from our card context. We use use Context Hook, and inside it, we pass Card context. Now, this will return object, so we can destructure it and get here head to cart function. Now scroll to the bottom, and in our head to card button, we add on click event, arrow function, and here we simply call our head to cart function. Now here, we have to pass two arguments. First one is product object, and second one is quantity. Unfortunately, we don't have both here. For quantity, we can simply pass one because here we don't have quantity input. But for product object, we have to do something. At the top in props, we can see here we are getting all variables for our product. So open up product list component. Here, instead of passing this all information in individual props, we can directly pass product object here. Remove this all and we just pass here product to this product object. Save this file, and now back to our product card component. Instead of getting all these, we get here single product object. Now let's replace all these values. So at the place of ID, we add product, question mark, dot underscore ID. Here we are using question mark because if product dot underscore ID is not available, then we get error. Now, at the place of image, we have product, question mark dotimag which is the array, and here we get our first image. After that, price to product, question mark, dot price, title to product, question mark, dot title. Rating to product, Qimark dot revs dot T. Next, rating counts to product, Qimark dot reviews dot counts and stock to product, Qimark dot STAC now we can simply pass this product object in this Add to Cart function. Save the changes and take a look. Open product page and click on Add to Cart. See the product is added in our card. Now here's one thing. As we know, our Add to Cart API is protected, which means only log in users can add product to card. So at the top, we again call use Contacts and pass here user Contacts. Now, this will return our user object and at the bottom, in our button condition, we add another condition. If user is not null, then we will show this head to cart button. Save the changes, and if we log out and in our products page, we don't get that basket icon. Now head over to single product page. And here we have also head to cart button. Now we call use Context Hook and passer user contacts here. This will return user object, so we'll store that in variable called user. And at the bottom, we wrap head to cart and also this quantity input and quantity heading and pass her condition. If user is available, then only show these elements. Now this will give us compilation error because we are returning more than one element. So how can we solve that right by using at fragments? So we wrap these and see it's gone. Save the changes and take a look. Here we get our product info without buttons. You can see how easy it becomes with use Context Sook. 165. Calling API for Checkout: Now, before we do anything, let's login again because we logged out in previous lesson. Now go to cart page. And here, let's call our last API, which is checkout API. In our application, we are not adding payment features because in adding any payment getaway, front end plays very little role. For example, in stripe payment, which is the most popular payment Gateway library to implement payment, we just need to call one API from front end. Most of the payment code goes to the back end. So it's not so much beneficial for adding stripe in this course, because our main goal is to learn react, and that's we are doing pretty well. Although if you want to know this, tell me in the Q&A section, I will update this section with that. But in my suggestion, you don't need that yet. Just focus on building nice and fast react applications. For order checkout API in the services folder, we create a new file called order services dot js. Now in this file, first of all, we import API client from Utils slash API client and here we create one function called checkout API inside this function, we simply call here api client dot post, and in endpoints Order slash Check Out. Now we don't need to pass any data because it will automatically fetch card data from the back end. Now, this expression give us promise, we simply return this Save this file, and in the card page component at the bottom in the checkout button, here we add on click event equals to here we pass checkout function. Now let's define this checkout function. Second, checkout error function. And here we call checkout API from Order services. Now, after this checkout, we have to empty our card. So here we add then method, arrow function. And in the Cali brackets, we first add Toast from react to S DiPi Library, and here we add success and here we pass our message, order placed successfully. And after that, we have to empty our card state. And for that, we need set card function. So we go to the app component and pass the set card function in our card context. Save this file and back to Card page. Here in this use context, we get set card, and in our function, we set card to empty card. Or we can move this set card before this API call. Now what if we got error for this API? So we add here catch method, and in the curly brackets, we had toast dot error, and as message, something went wrong. And after that, we will set cart back to previous state. So at the top, we define new variable called old cart equals to array, and here we spread cart array. Now in the catch method, we simply pass set cart to old cart. Use the changes and take a look. Click on Checkout button, and our cat is set to empty. Now, let's verify this. So in our Mongo we we compass, open our CAT Wi database. Here we have order collection, and inside this, we have our confirmed order and status set to paid. 166. Exercise Getting Users Order: Now it's time for one more little exercise. Here on our My Order page, we have to display all order details about current user, and you get that current user order info from this GAT API. Suspend two to 3 minutes on this exercise, and I know you can complete this exercise. 167. Solution for this exercise: Now, let's see the solution of our exercise. Note that this exercise has two solutions. So first one, we create another function in the order services file for My Orders EPI, but that is the long solution. So the Sten Street solution is we can use our custom hook, which we can use for fetching any kind of data. So here in our component, we call use data hook at the first parameter, we pass our endpoint, which is order. Now, this will return object with data, which we can rename to orders. Also, here we can get error and is loading variable. Now here we can set condition for this table component, which is if order is not null, only then display this table component. Now we have to just display these orders in our table. In T body, at the top, we had curly brackets, orders dot Map, and here we get single order, and also we get here index. Now we will return simply this table row. And pass key to order dot underscore ID. And inside this row, we add table data, and first, we show index plus one. After that, for products name, we leave it same for now. Next, we have total, so order dot total, and at last, we add order dot status. Save the changes and take a look. See here we get our order details. Now we just need to show product names. So for that, we create a new function. Call Get product string. And as the parameter, we get here, single order, error function. And first of all, we do order dot products, dot MAP. I name in the curly brackets, we call this get product string function and simply pass here this order. Save the changes and take a look. See, here we get our product string with the quantity. So it's working pretty well. Now, let's add here loader. Before our table component, add I I loading is true, then we show loader component. And also for error, here we pass new Cully brackets. Error is available, then we return emphasis tag with class name, form error, and here inside this, we show error. Save the changes and take a look. See, it is working for us. Perfect. 168. Creating Protected Routes: Now in our current implementation, we have little bug here. So when user is logged in, only then we are showing this Moder, logout and cart links. Now, if we log out, then we don't see these links, but here is one thing. If in our URL, we set path to slash CAT and hit Enter, then we also access those protected routes, and that's not we want, right? So if user is not logged in and they try to access protected routes like Moders or CAT page, then we will directly redirect them to the login page. So for implementing this, we will open our routing component. Here we know for defining route, we use route component, and here we pass path and element props. So here we are going to define a new route component. We will call this protected route. This component will be just wrapper of this route component, which simply checks if user is not available, then it will automatically redirect them to login page. Otherwise, it will redirect to that protected page. Don't worry, see this and all doubts fill clear. In our routing folder, we create a new component called protected route dot JSX. Add here Boilerplate code for this component. Now, first of all, in this component in return, we call Get user function from user services, which will return user object or if token is not available, it will give us null value. So if user is available, then we return Outlet component. Else we redirect to login page. So here we use Navigate component from React router Dom and pass to attribute to slice login. If you forget outlet, just for quick repressor, at the place of this outlet, our nested routing components will show. Don't worry, save this file and in the routing component, which routes we want to protect. Right, this is last three routes, cart, Moder, and Logout. So at the top, we add route and wrap these three routes which we want to protect. Now in the element, we pass our protected route component and that's it. Save the changes and take a look. Here we are not logged in, and we try to access card page and see, we redirect to the login page. Now let's log in with email and password and try to access card page. And now we can access this page. So it's working both ways. Now let me explain you what is happening here. Here we are using natural routing. So when our application, want to navigate from these three routes, first, this protected route component will run, and inside that component, we have condition for Outlet and navigate to login page. So if user is logged in, then this element display at the place of outlet, simple as that. So that's how we create protected route for our application. 169. Redirect to previous protected page: Now, in previous sesson we seen when we are not logged in and we try to access protected routes like cart page, then we navigate to the login page. And if we log in with our email and password, we redirect to the homepage. Ideally, we should again redirect to that protected route, which we want to access. This is not a big issue, but it will little bit boost our user experience. So let's fix this. So for that, our protected route component we have to pass previous location with this navigate component. Don't worry about that, see this, and at the end, you will understand all of this. So before return, we call use location hook from Rea router doom let's store it in variable, call location. Now this location has all informations about the current page location. So let's simply console dot log this location. Note that only protected pages will access this protected route component. And for now, let's comment out this return statement. Save the changes and take a look. Open up Console, and I simply logo from here and try to access my Orders page. See here we get our location object, and in that object, we have this path name which we want to access. Back to VS code, remove this console dot log and also remove this command. Now we somehow need to pass this location dot path name to our login page. In this navigate component, we can pass additional data in the state props. State equals to C brackets for adding JavaScript code, and here we add object with property from, and we simply pass here this location dot pathname. Save the changes, and now in our login page, we just need to access this from state. In our login component at the top, we again use here, use location hook from Rea Router doom and store that in variable called location. Now let's consult that log, log in location, and we pass here location. Save the changes and take a look. See, here we get login location object. Open that and see, here we have state, and in that we have from property to our previous path, which is CAT. So here, in the onsubmit function, before window dot location, we have location and we fetch state property using object destructuring. Now here in the window dot location, we simply add condition. If State is defined, then we will redirect to stat dot from else we simply redirect to homepage. Save the changes and take a look. Log in in this form and see we redirect to the card page. So it's working. Now we are almost done here. But currently we are logged in in our application, and if we try to access log in page or signup page, then also we get these pages. So we should redirect user to the homepage if user is already logged in. These are very rare scenarios, but it's better to take care of them. So let's fix this. So in our login page component, here before our JSX return, we add condition. Here we call at user function from user services. And if it returns a user, we will return here, navigate component from react Router doom and navigate to homepage. Save the changes and take a look. Now, if we try to access login page, see, we redirect to the homepage. Let's do the same for signup page. Copy this I condition, and in our signup page component before our JSX pass this code. We simply import Get user from user services and also import navigate component from react Router doom, and we are done here. So that's how we handle protected APIs and protected routes in react applications. You can see it is very simple and easy to use. 170. Section 15 Fixing Some Issues: So in our application, we have a couple of things to do. First of all, at the homepage, we have to fetch feature products from the back end and display them in this section. Next, we have links for B now here. So on this button, we will add this products page link, and that's it for the homepage. Now let's go to the products page. Here we have short option, but we didn't add that functionality. So we have to do that. Next, we have another important feature which is searching our product. So we will complete the search feature with auto suggestions. You can make list for this task, and as you complete each task, you can check that as completed. That will give you more clarity and you can manage to complete one task at a time. You can see this is my notes when I'm completing this project. Also, you can take all these task as the exercise and try to solve it before watching the solution. So in a couple of lessons, we will complete this project. 171. Fetching Featured Products: Now, let's start with fetching feature products, soap and feature products component. And here, in this component, we call it used data hook. Now at the first parameter, we pass our endpoint, which is slash products, slash featured. Now, as we know, this used data returns object, so we destructure it, and here we get data error and ease loading properties. Now, let's simply console dot log this data. See the changes and take a look. Open up Console and see, here we get array of three products. Now we have to just display them here. So open up product list component and in the product list, do copy this data dot products and skeleton both. And in our features products component at the place of the three products card, we paste it. Now, first, we change this data dot products to data only, and also here data dot map because we are getting array in our data. After that, here we need to import the skeleton component. Here we import product card skeleton. As we need to define the skeletons array. At the top, skeletons equals to array. Now, how many skeleton we want to display? We want three skeletons. Here we add one, two, and three. Let's display our error. Again, back to product list component and simply copy this error. And paste it in our features products list. Save the changes and take a look. See, here we get our features products. We complete our first task. We can check that task as completed. Now let's also fix this by now link. First of all, in products, here we have our iPhone 14 product, right click on this image and copy link address. Now back to VS code and open up homepage component. And here in the first hero section link, we paste that link address. And at the beginning, we remove our base URL. We don't need it. Now, same we do for the second hero section. So here we also have MacBook. I know this is not tt product, but we don't have Mac studio and that's why we can redirect user to MacBook. So copy this link address, and in our component, we paste it here. Also, remove the base URL, save the changes, and take a look. Click on By Now button, and we redirect to the iPhone 14 page. But it is refreshing our page. Let's stop this. So back to VS code and open up hero section component. And here at the place of Anchor tag, we add Link component from React Router doom and rename this HF to two attribute. Save the changes and take a look back to homepage and click on Bynw button and see, we redirect to that page. So here we complete our second task also. Now in the next lesson, we'll work on our search bar. 172. Fetching Products by Search Query: Now, let's add search products functionality. So here is the demo of that. When we search something in our search bar and hit Enter or click on the search bar, we only fetch that data from our products API. And you can see when we hit search that search string is adding in the query string. And also, here we get autosuggon for search query, and we can also navigate with the arrow keys. It is very simple. Let's see this. In our current implementation, we have to only set our search input in our URL query string. And from that query string, we will pass that search text in our API call. Same as we do in our category. So in our NBR component, we have our search input. So first of all, we need to get text from the search input. So at the top, we add here used it and add snippets and give it a name, search and set search and pass empty string as default value. Now in our search input box, first we pass value to search variable and after that, pass onchange event and inside it, we get event object, error function, and we simply set search to e target dot value. So here we get our value in search state. Now we just need to set it in URL query string. So first of all, in our form tag, we add on submit event and pass ER function, handle submit. Now let's define this function, handle, submit. Here we get event object, and first, we set E dot prevent default. And what will it dot? It will prevent a default behavior or form. Now, after that, here we pass one condition if search is not equals to T string. Then we will set that search string in the query string. So here we have two ways. We can use use search params, or we can use use Navigate hook. Choice is yours. We seen both hook in react router dom. I personally like to use here use Navigate because it is simpler than use search params. After use State, we call use Navigate hook from react router doom and it will give us Navigate variable. Now let's add Navigate function in our handle submit. And here we pass our URL. So in Betts, we pass slash Products, question mark, Sarge equals to dollar colli brackets, Sarge. Save the changes and take a look, write something and hit Enter. Navigate to the products page with search query string. Now remove this text and just and hit Enter. See, we are getting space in the query string, and that's not we want. In our handle submit function, in Navigate we pass search dottremFunction. This will remove all unwanted spaces. And also here addition, we add search dot cream. Save the changes and take a look back to our home page. And when we add spaces and hit enter that will not redirect to the products page. So our half task is done. Now we just need to pass this search query in our API call. So on a product list component, first we get our search string from query string. So query, we define const, search query equals to search dot GT and pass here query string variable name, which is search. Now we simply pass this search query in our params. Before our category, we add search to search query. And as we change our search query, we should call this a PI, so we have to add search query in this dependency array. Save the changes and take a look. Search something here and hit Enter. See, we get only two products. So our search query is working. Let's try one more time, write something and hit Enter. See it is working. Now let me show you one bug. Go to the products page and scroll to the bottom. So our page is set to three. Now search something and you can see we don't get that data. Why does that happen? Right, because we don't have page three for this query string. So what is the solution for that? Right, we have already seen that. So we have to set page to one. So in our use effect, we have done that for our category. Now we simply add here search query. The changes, and now our bug is gone. You can see how simple it is to add search functionality in react. And here, our third task is completed. So in ecommerce application or websites like YouTube, this search functionality is very useful and important feature. So always remember the logic of search bar. First, you have to set query string in the URL and then pass that query string in the API, simple as that. 173. Auto Suggestion in Search bar: Now currently, if we write something in search bar, we don't get any suggestion for products name. So in this lesson, we will show autoization for our search bar. So in our N Bar component, after our handle submit function, we add use effect hook and inside it, we add callback function and dependency array with Search state. So when our search change, this callback function and inside this callback function, we will call our suggestion API. So for API, in our services folder, we create new file called product services dot js. Now inside this file, first of all, we input API client from Utils API client module. After that, we create a new function called Get suggestions API. And here we get search as parameter, and inside this function, we simply return api client dot GT now for endpoint, we add backticks, slash products, slash suggestions, question mark, search equals to dollar curly brackets, search. We have done this so many times. Now let's simply export this function. Save the changes, and back to our Navbar component. Here, first we add condition if search dot trim is not equal to empty string, then only we call our API. Here we call get suggestions, API function and pass here our search. Now this function will return a promise. So here we use then method, and inside it, we get response. And for storing suggestions, we need to create a new state variable. So after our search state, we add one more use state hook called suggestions and set suggestions. And as a default value, we pass empty array. Now in our then method, we simply set suggestions to response dot data. After that, we add catch method, and here we get error object and simply console dot log this error. So here we add our condition I search is not empty and else if search is empty, then we simply set suggestions to empty array. Now let's console dot log the suggestions array, save the changes, and take a look, write something in the search bar, and in the console, here we can see we get these suggestions. These suggestions is array of object, and each object has only two properties, underscore ID and title. So here we have our suggestions. Now we just need to display them below our search bar. So first, we have to add our elements, and then we will add style for suggestion list. After our search button in the form tag, we add new under list with class name, search underscore result, and inside it, we add list item tag with class name, search underscore suggestion, underscore link. Now inside this, we simply add link component from Rea router doom. Pass to prop to slice products for now. Inside this, we write iPhone 14 Pro. Now the reason we add here Link component, so when we click on that suggestion line, we will redirect user to their product page. Save the changes and take a look. See, here we get our suggestion link. Now let's add style for that. Sop Nabar dot css file. After our search button, we add dot search underscore result, colli brackets, and inside that, first, we set position to absolute top to 100%, and left to zero. Now to use position absolute, we have to make our form position to relative, scroll up, and in the Navbar form, we add position to relative. Now back to our search result. And here we add with 200% margin top to ten pixel, water to one pixel, solid has CD CD CD, border radius to five pixel, background color, to white, and at the end, Z index to 9999. Now after that, we add style for search suggestion link, so dot search, suggestion, link, and inside the curly brackets, we set display to flex. Now, after this, we add style for anchor tag, which is available in link component. Dart surge, suggestion, link, and here we target anchor tag, curly brackets, and here we simply add width to 100%, adding to ten pixel and 20 pixel, one size to 18 pixel and cursor to pointer. And at the end, we add HR effect for our link. Dart surge, suggestion, link, Callan hover. And in the curly brackets, we set background color to a E three, E three, E three. Save the changes and take a look. See, our link looks good. Now let's simply show our suggestions array. Back to our Neva component, and in our unordered list, we add CL brackets, suggestions dot MAP. Here we get single suggestion, arrow function, and simply return this list item. Now, first and foremost, we add key attribute to suggestion dot underscore ID. And in the link component, we add Ci brackets, back ticks, and inside these, we add slash products, question mark, search equals to dollar Ci Brackets, suggestion dot title. And at the place of this hardcoded title, we also add suggestion dot title. Save the changes and take a look, type something in the search bar and see we get suggestions. Now, if you click on any of the suggestion, we redirect to the products page, and our products will display according to dat. But the suggestion list will remain the same open. We have to close it. So here in our link component, we add on click event and inside error function. And in Cul brackets, first, we set search. And set suggestions to empty array. Save the changes and take a look, write something and click on suggestion. See, our suggestion is gone. Now we also need to do the same in our handle submit function. So after this navigate method, we simply add set suggestions to empty array. Save the changes and take a look. See, now it's working very well, but here is one thing. Even if we don't have any suggestions, we still get these lines. So right click on it and go to inspect. Here we can see it is our unordered list border. Let's fix this. So back to VS code, and we wrap our unordered list with curly brackets and simply pass here condition if suggestions dot length is greater than zero, only then show this list. Save the changes and take a look. See now our search bar is working well. Now here you might think, what is the benefit when we click on suggestion and redirect to the page which has only one item. So in our database, currently we have only single item for each product. But when our database grows, we might have iPhone 14 with multiple colors, and at that time, this page will display multiple products. 174. Navigation for Auto Suggestion: Now in our search bar when we get auto suggestions, we have to click on that suggestion for search. But in real world, 99% of users don't click on the suggestion link. They like to use ARO keys, and that is the good user experience. So in this lesson, we will see how to add Ero keys navigation for our suggestion list. So first of all, we create a new state variable, call selected item, set selected item, and as the default value, we pass here minus one. Just remember the logic and your all doubts will clear. So when we press down key, this selected item value will increase by one, which is zero. And we put condition if selected item is same as index of our suggestion row, then we will highlight that row, simple as that. So first of all, in our search input, we have to pass one event called on key down, which will run on every time when we press any key in this input. Here we pass function called handle key down. Let's first define this function. Write const, handle key down. We get here event object, and inside this, we simply add console dot log e dot kee. By using this e dot key, we get pressed key name. Say the changes and take a look, select the input box, and press up arrow and see here we get arrow up. I press down arrow and also Enter. See, here we get our key names. Now we can add our conditions according to that. So in this function, we add our first condition I K equals to arrow down. Make sure you write the same string, otherwise it will not work. Now inside this, we write set selected item. Here we get our current value arrow function, and we return current plus one. After that, we add another condition, if K equals to arrow up. And inside this, we simply copy this expression and paste it here. But we just replace this to current minus one. Now at last, we add one more conditions if e dot K equals to Enter and also selected item should greater than minus one because if selected item is minus one and we press Enter, then this will give us error. If selected item is greater or equals to zero, then we navigate to that link. So first, here we define suggestion equals to suggestions, and in square packet, we pass selected item. And after that, we simply navigate with that search. So how can we get that simple by using navigate method? So here, we copy this link from link component and paste it in this navigate method. After that, we set search to empty string and also set suggestions to empty array. Now, last step, we have to highlight the current active index. So for that, in our list item tag, we cut this class name and addheKLbackets, pass her condition. I selected item equals to index of this suggestion, then we add search suggestion link and active class. As we just add search suggestion link. And also we have to get index from this map method. Save this file, and let's define CSS for this active class. So open Navar dot CSS file, and here in our *** style, we add another class called search suggestion link dot ActV save the changes and take a look, write something and press down and up keys and see it's working. Now we hit Enter and C, Link will open. But here, when we reach to the bottom and again press down arrow, then our selected item is not highlighted and same for up arrow. So when we are at the top of our list and again press up arrow, then we have to set our selected item value to the last item. Go back to Naver component here in our handle key down function for arrow down, we pass here condition if current equals to suggestions dot length minus one, which is the last item, then we return to zero, which is our first item, else, we will return current plus one. Now for arrow up, we pass her condition. If current equals to zero, then we return suggestions dot length minus one, which is our last item, else, we return current minus one. Save the changes and take a look. See, we can move top to bottom in our suggestion list, but here is a one bug. If we select last item, and then we keep writing, then we have to press upkey multiple times, and that is the bad user experience. To solve that here in our handle key down function. Add one condition I selected item is less than suggestions dot length. Only then we run this logic. So move this code in I condition, and else we will set selected item to default value, which is minus one. Save the changes and take a look. See now it's working properly. You can see how simple it is to add error navigation for our suggestion list. 175. Debouncing method for getting suggestion: Now, currently, in our implementation, we did something very wrong. Let me show you. So in our developer tools, open up Network tab, and type here something in this search bar. Here we can see we are making API call to the back end every time a user types a character in the search bar. For example, here we are sending six request, and we really don't need the first five response. So when we are sending so many requests, our application slows down, and also load on server will increase. So to reduce the number of API calls here we can use technique called debouncing. Debouncing is a method to delay the execution of a function until a certain amount of time has passed. For example, when user type something in search bar, after some delay, we will call our API. Let me show you how we can do that. It is really simple. So in our use effect, here we add set timeout function. As we know this except callback function and a second parameter, we have to pass time in milliseconds. Here we pass 300 milliseconds. Whatever we add in this callback function, it will run after 300 milliseconds. We will move this logic in our callback function. Good. Now we have to add cleaner function for this timeout. We store this timeout in variable called delay suggestions. At the bottom for cleanup, we return callback function, and here we simply clear time out and pass delay suggestions. Save the changes and take a look, refresh the page, serve something here, and we can see here we are sending only one request, so it's working. Now let me explain to you what is happening here. When our search state is changing, the set timeout function execute and after 300 milliseconds, we are calling our suggestions API. Now, if user types another character within 300 milliseconds, the timeout is reset and the API call will postpone again. I user don't write any character in 300 milliseconds, only then this API will call. Can change these milliseconds according to our needs, but 300 milliseconds is the average time, not too slow or not too fast. So debouncing method is very useful if you want to limit the number of API requests. So our one more task is completed here. 176. Sorting Product List: Now let's complete our last task, which is shorting our product list. So when a product list component, first of all, we will define one state variable for storing sorting value, and we call it short B and set short B. And as a default value, we pass empty string. After that, we will create another use state for storing the sorted products. And as a default value, we pass empty array. Now in our select tag, first, we get our current shot value. So we adhere changed event, and inside it, we get event arrow function, and simply set sort B to E dot target dot value. Now let's set shorting functionality. So in our previous project, we shot our movies array using low desk library. Now let me show you another way to add shorting without using any library. So first of all, here we add use Effect hook and pass callback function. In the dependency array, which variable we add. When our shot by value will change, we want to short our products and also when our data change, then we also want to short products. Now let's write logic for shorting. First of all, we will adde condition if data is available and data dot products is available only then our shorting will run. So inside this condition, first we create the copy of our products array. So Cons products equals to array, spread operator data dot products. Now let's at condition I short B equals to price descending, and inside this, we will use sort method. So we write products dot SHOT. Now, let me explain your short method quickly. So inside this sort method, we get two parameters A and B. A is the value of first item, and B is the value of second item. Don't worry about that, see this. For descending, we have to pass here, B minus one, and for ascending, we have to pass A minus B, simple as that. Now in our case, we have array of objects. Here we return B, which is our second item price, minus A, which is our first item dot price. Now, this will return sorted array, we simply wrap it with set sorted products, and that's it. Now let's add another condition. So C sort by equals to price ascending. And inside this, we will copy this expression and paste it here and change this condition to at price minus B dot price. Now let's duplicate these both conditions, and here we change I to sf. Now at the place of price descending, we pass rate descending. And in our sort method, we set condition to B dot reviews, dot rate, minus A dot reviews dot rate. Now next, we have rate ascending and we change compared function to A dot reviews dot rate minus B dot reviews dot rate. Now if we don't have this sorting value for that, we adde, and we simply set sorted products to products. Now, in our JSX, at the place of data dot products, we at sorted products dot MAP. Save the changes and take a look. Change the shot to price high to low and see our products sorted by price in descending order. Always remember for ascending order, we have to pass compared function to A minus B, and for descending, we use B minus one, and that's it. That's how we implement shorting without any library. But this sorting method will only run for numbers. In our previous project, we have to short movies by date, and that's why we use Low desk library. 177. Section 16 Performance & Code Management Hooks: Welcome to the updated 16th section of the ultimate reactors. Some students are telling me to explain some more react hooks. So in this section, we will see some hooks of react by which you can improve your application performance like use memo and use callback. We will also see when we can use these hooks and when we can't use it. And after these two hooks, we will see another hook for code management, which is use reducer hook. This is the mini section, so let's quickly start this. 178. Understanding useMemo hook: Now let's understand what is use memo and when we need it. Use memo is a hoop which is used for improving the performance if we have expensive calculation in our react application. Now you might ask what is expensive calculations? Sometimes in our application, we have complex calculations like finding the sum of 1 million products or finding the factorial or finding the Fibonakiseries, which are really big calculations and it can take time to calculate the result. This situation, we can use use memo hook for reducing the time of unwanted calculation, and also we can avoid unnecessary renders. And because of that, we can improve our application performance. Let me show you this practically. So for demonstrating these hooks, I'm using a new project because we don't want to mass our ecommerce application. And after learning that, we will implement these hooks in our project. So you can just see these and then you can implement. So here, I created one state variable called count. And in JSX, I created two buttons, minus and plus, and at the center, we display count. Now, let's suppose we have to find the total sum of 1 million products. This is just an example. Don't worry about that. So to demonstrate that, I created this expensive calculation function, which basically runs this long for loop and return the sum of count number. And in our JSX, we are simply displaying this total. Let me show you how it looks in browser. See we get here default total. Now let me click on this plus button. See, it is taking two to 3 seconds per calculation. Now this is completely fine because we need to calculate some, but here is a one thing. Even if we do something in this component, this result gets calculated again. Let me show you what I mean. So here in our component, I create a new state variable called dark theme and set dark theme. As the default value, I pass false. Don't worry, this is just a demo. I'm not going to implement dark and light theme here. Now, after our total, I add one du and inside this du I add tag and display here theme. If dark theme is true, then we display dark mode L Light mode. And after that, I add one button called togal theme. And for this button, I add on click event simple set tag theme to false dag theme. Now let's see how our application works. So here, if we increase or decrease the count, it is taking two to 3 seconds, which is good. Now, let me try to togal theme. Can you see it is again taking two to 3 seconds to change the theme? Because that expensive function is calling again. We can see that by using this console line. So why does it is recalculating this total? Right, because we change the theme state. And we know that when we change theme state, this whole component gets re render, and that's why this total counts again. So the ideal way is when we change this count variable, only then our expensive calculation function should run. Otherwise, it will slow down our application. We get the problem which is unwanted rerender for calculation, and now we can solve this. Here, we can use use memo hook for stopping the unwanted calculations. Just see this and you all doubts will clear. At the place of this expensive calculation function, we call use memo hook and same as use effect hook for use memo, we also need to pass to arguments at the first parameter callback function, which we want to run inside this, we want to call expensive calculation function. Pass our count as argument. At the second parameter, we have to pass dependency array in which we have to pass variables. Whenever these variables modify, then only this function will call and that's why I pass here count. Whenever this count variable gets modified, this expensive calculation function runs and whatever we return from this function, it will add in our total variable. Let's check it is working or not. LconPlus S, it is taking two to 3 seconds. But now if we click on togal theme, it is immediately changing this. So that's how use Memo hook can improve our application performance by stopping unwanted calculations. Now, let me ask you one question. How can we achieve the same result without using use Memo hook? What I mean is if our count variable gets modified, only then this expensive calculation function should run. Thats we have another method, think about it. Right. We can achieve the same result with use effect hook. Here is the solution with use effect hook. But in this implementation, we have to create one more state variable called total and set total. But in use memo, we don't need to create separate state variable. This total works as total state variable. So that's one extra step for this use effect implementation. Otherwise, the both works almost same. So it's better to use use memo hook for handling complex calculations. 179. Exercise for SubTotal: Now it's time for little exercise. So in our Cart wis project, let's modify our subtotal logic and use use Memo Hook for that. I know you can do that very easily. So give it a try and then was the solution. Now let's see the solution. Open up cart page component, first of all, let me remove this subtotal state variable. Simply at the place of this use effect hook, we will add use memo hook. Nice auto input works. Now, at the place of setting this total as subtotal, we simply return that total because use memo always returns value. Do you remember? And at last, let's store this total in variable const subtotal. Now let's remove use effect and use input from top. We don't need it. Save the changes and take a look. See, it works the same as before. You can see how simple it is to use use Mamo hook. Ss use effect, use memo takes two arguments. First one, callback function, which always returns value. And if we don't want to return any value from this callback function, then why we use use memo hook, right? And second argument is array of dependencies. So use use memo hook when you need to handle complex calculations. Now in the next lesson, I will show you very similar hook, which is use callback hook, see you in the next lesson. 180. Understanding useCallback hook: Now, let's learn about use callback hook. This hook is very similar to use memo hook, which means it is used for improving the performance of our react application and prevent unwanted re renders. The only difference between use memo and use callback is use memo returns a value and use callback returns a function. That's it. I know this is a little confusing. Let me show you practically. So here, I remove our previous use mammo code and first of all, I create one state variable using use state called counter and set counter, and default value to one. We create another state variable called set theme and as the default value to light. Now in our JSX, I create here as to tag and simply display here theme and in Gully bracket theme. Just see this and you will understand use callback Hook. Now for togling the theme value, we create one button and pass here to ogle theme. For onclick event, I add here function reference to GL theme. Now let's define this function at the top. So Cons togal theme equals to arrow function and simply call set theme function and we get here previous value, arrow function, and we pass here condition. I theme equals to light, then we change it to dark else we change it to light. Now you might think, why I'm not displaying counter. So for displaying counter, we create a new component in our source folder called counter dot JSX. I know you have a lot of questions, but after the results, you will understand what I want to show you. Let's add boilerplate code using RAFC and here we simply return tag and display here counter curly brackets, counter. For changing this counter, we will create one button called increase. For increase the counter, we pass on click event and simply pass here, increase counter function. Now, how can we get the counter and increase counter function? Right, by using props. We destructure here, counter, and increase counter function. Save the changes and in the a component, before this has two tag, we just add counter component. Now we have to pass two props counter to counter and increase counter to increase counter. And at last, we have to just define this increase counter function. So const increase counter equals to set counter. Here we get previous value, error function, and simply previous plus one. Save the changes and take a look. See, when we click on Increase button, counter is increasing by one, and when we click on Togal theme, theme are changing. Perfect. Now here is one thing. In this counter component, suppose we are performing some task, which takes 500 milliseconds, which is half second. So to demonstrate that, we add here first, console dot log, counter component, re render. And after that, let start time equals to performance dot now. This performance dot now function will return the high resolution time stem. For now, don't worry about that. And I simply adhere Y loop and give it condition if performance dot now minus start time is less than 500, then run this loop. This will simply add delay of 500 milliseconds. Save the changes and take a look. Open up Console and refresh the page. Now click on Increase button and see here we get counter component rerender message and also have second delay in increased counter value, which we want. Perfect. But here is the one problem. Even if we click on Toogle theme, it is also rendered the counter component. After 500 milliseconds delay, our theme is changing. But changing the theme should not re render the counter component because they are two different state. So here, our counter component gets unwanted re renders and because of this, our application slows down. Can you see the problem to demonstrating more clearly here in the app component, we adhere class name to theme. And at the top, I imported app dot CSS file. Save this, and in the app dot CSS file, first, I add DU and in the C bracket, padding to 20 pixel. After that, we add style for dark class. And inside this, we add background color two has 101010 and color two has FFE 400. Save the changes and take a look. Click on to Gal theme. See, we can clearly see the delay. So we need to solve this issue of unwanted re renders, and that we can do with Us callback Hook. 181. How to use useCallback hook in React: Now, let me show you how we can use use Calbeck Hook to prevent unwanted re renders. So as you might know, use callback always returns a function. So first, we need to identify which function causing unwanted re renders. Can you identify right. It is increased counter function because when we click ontogal theme, our app component gets re render and because of this increased counterfunction re created. That's why our counter component also gets rerender. But our theme state is not related to counter component, then why we need to render counter component. In simple words, counter component should re render only when we change our counter state. Let me duplicate this increased counterfunction. Comment out this one. You can clearly see the changes. Now use callback hook syntax is same as use memo syntax. We can wrap this arrow function with parenthesis and add here simply use callback Hook. Now at the second parameter, we need to pass dependency array. In that dependency array which variable we will add we counter variable. Are really smart, good. So when the counter variable change, only then this increased counter function will recreate it. See the changes and take a look. Click on Togal theme, and it still gets delay. So to complete this logic, we have to do one little thing. So in which component, we want to stop unwanted rendering, we have to wrap that component with mammo function. So here at the top, we can import mammo from react library. And when we export that component at the bottom, we simply wrap that with mammo function. See the changes and take a look. Click on Togal theme and see it is working very smoothly without we are getting rerender message. If we change our counter, only then our counter component rerender. That's how we will prevent unwanted re renders. Now let's recap use Callback Hook. Use Callback hook is used to prevent unwanted re renders and help us to improve our application performance. You might ask, should we wrap all functions in our application with use callback hook? The answer is no. We should only wrap those functions which are causing unwanted retenders and delay. Is there any shortcut trick to find those type of functions? The answer is yes. There is one trick which I use when I started to learn use callback hook. Whenever you pass function as props, and there are another state in that component, only then you have to use use callback Hook. Let's check this trick work for our app component or not. So first point, function passes props. In our app component, we are passing increase counter function as props to counter component. And second point, there should another state in that component. So here we have theme state other than counter state. So this trick is working. I hope you understand use callback hook use Mamo and use callback is used to improve application performance. When your react application starts slowing down, you can take a look to your code and see if you can use use memo and use callback or not. It's not compulsory, but you can use them when you need it. 182. Exercise for useCallback hook: Now it's time to practice use Calbeck hook. So in our Cows project, you have to find if there are any component in which use callback is needed. If you find some, you have to use use Calbeck hook in that component. So spend some time on this exercise and remember those two points to identify. Function pass through probes to the child component, and there should one state variable. So give it a try and after this, see the solution. So in our Carwis application, first we check our root component which is app component. So here we have state variables, user and CAT also we are passing function from parent component to child component. So we can implement here, use callback hook. Here in the At to cart function, we simply wrap this callback function with parenthesis and simply add here, use callback and for second parameter, we add dependency array and inside it what we add, right, we add card state. Now for removed from card function, we wrap its callback function with parenthesis and also at the top, we add use callback hook and for second parameter, we add card state independency array. Same we do for this update card function, wrap it with parenthesis and add here use callback and dependency array with card state. Now for Get card function, we wrap its callback function with parenthesis and add use callback hook. Now what we add in this dependency array, should we add card state? No, we don't need card state here because if we add card state independency array, then when our card state will change, only then this Get card function will run, and we don't want that. We want when user state is changed, then we get card details. So we add here user state, and that's how you need to think about adding dependency. And that's it. We add use Callback hook in our app component. Save this file, and we have to wrap all components which are using this function by mammo function. I quickly wrapping these components with mammo function. Save the changes and take a look. See, it works the same as before. Using use memo and use callback hook, we can improve the performance of our react application. Now you might say, we don't see the performance improvement. Yes, currently you can see that. But when our application becomes big, at that time, these hooks are really helpful for improving the performance. That's how you can use use memo and use callback hook. Now in our application, you find any place where you can add use callback hook, then you have to implement use callback at that place. This is one more little exercise for you. Check our application components and if you find the place, then you can add command in the Q&A section. Other students will also get that component for update. Su in the next lesson. 183. useReducer hook: Now, let's see another react hook, which is use reducer hook. So use reducer hook is used to organize complex state and its method. In simple words, use reducer is used to make our component more clean. I know this is a little confusing, so let me explain to you that using one simple example. So imagine we have one little application in which we have one count, and we have three buttons, increase, decrease, and reset. When we click increase, count increase by one. If we click decrease, count decrease by one, and if we click on Reset, then our count gets reset to its default value, which is zero. Its code look like this. At the top, we have count state using us state hook with default value zero. Now for this state, there are three methods, or we can say there are three functions. Increase count, decrease count, and reset count. Simple as that. Now this code is little bit unorganized, so we can organize this code by using use reducer hook. I comment out this code and call here use reducer hook. Now, this hook accepts two arguments. First one is reducer function, which is the function who decide which methods we want to call, like increase or decrease or reset. Second argument is default value of our state, which is zero, right? Now here, we can also add one more argument, which is used to delay to initialize the state value. But usually, we don't use it. So for now, we don't want this. Now, same as our use state hook. This use reducer hook also returns array, which has two items, current state and one function by which we can update the state. So C first we get our state count. Second, the function per updator state, and we call it as dispatch function. Dispatch means sending something. It is the most common name per use reducer. If you want to take another name, you can also do that. It's totally up to you. Now, let's define our reducer function. Outside of our component function, we define a new function called reducer, which is the most important part of use reducer hook. So inside this function, we will write our all logic for our use reducer. I know this is a little confusing, but after completing this lesson, your all doubts will clear. So this use reducer function has two parameters. First parameter is state, which means where our application is currently at. And second parameter is action, which means which action we have to perform. For example, increase the count, decrease the count, resetting, et cetera. Now, this function will return the updated state of our count state. So for now, I'm just returning state, which is current count value plus one. Now to call this function, we use this dispatch function. So here, in increase count function, I just call dispatch function and pass nothing inside it. Also, I need to comment out this set count line. Now let's see what we get. So save the changes and take a look. Click on plus button and see counter is increasing by one because in reducer function, we return here state plus one. If we change this to state minus one, then it decrease the count value. When we call this dispatch function, this callback function will run and whatever value we return from this function, that value becomes the current state value. Simple as that. Now you might ask, how can we perform other actions like increase or decrease for different functions? For that, we can pass object in this dispatch function. In this object, we add one property called type, and we simply pass here type to increase in all capital. No compulsory all capital, but it is better practice to highlight the type of action. Now by using this type, our reducer function will know which task we want to perform. Here, we can put condition according to this type. We can use I s or we can also use switch case. I like to use switch case, switch, and here we pass our type property. Now the question is, how can we get the type property? We get type property using this action parameter. Here, we simply write action, which is this object and dot type. Now, inside the curly brackets, we add case, increase, colon, and here we return state plus one. Now we add another case, which is decrease, colon, and here what we return? Wight. We return state minus one. Next, we add one more case which is reset. Colon and here we return zero. And for safety, we add here default case, and we simply return here state as it is. If by mistake, we add other action type, then that will not cause error. So reducer function is ready. Now we just need to dispatch different type of action. Copy this dispatch function and simply add it in decrease count function and change this type to decrease. Next for reset, we change this type to reset. Save the changes and take a look. See, our application works the same as before. You can see now our code looks a little bit more organized. By using user reducer, we can organize our code. Let's recap this use reducer hook. Use reducer accepts two arguments. Reducer function which simply manage which type of actions we are performing and what it does. And second argument is default value. Now, same as use state, use reducer also returns array with two items, state and dispatch function. This state is current state value, and using this dispatch function, we can specify type of action. Whatever type we pass from here, it will run its case in our switch case, simple as that. So use reducer is nothing. Just make our code more organized. If you are satisfied with your current code, then you don't forcefully apply use reducer for that component. It's totally up to you. Don't get confused by that. Now you might say, by using this reducer function, our code looks more ugly, and that is true. The solution is we can define this reducer function in another file and simply import that function here in use reducer hook. In our source folder, we create a new folder called reducers inside this folder, we create a new file called count reducer dot js. Now, from a component, we cut this reducer function and paste it in count reducer file. Also, we can rename this staate to count. I think this makes more sense and also change the function name to count reducer. And then we simply export default count reducer. Save the changes, and in our app component at the place of this reducer, we add count reducer. Save the changes and see now our code looks more clean. That's how you can make your component clean. 184. Exercise for Reducer: Now it's time for little exercise. In our Card wise project, we have our app component in which we manage different methods for modifying the card state. So you have to implement use reducer for the card state. Also, the hint is in reducer function, we need to only apply the state update logic, not calling an API. It should be separate. Here is the case one for card state. From this example, you can create other cases. This is going to be fun, spend some time with this exercise and then see the solution. 185. Complex Actions for Reducer: I hope you solve this exercise, or at least you try to solve it. Because to use use reducer hook in complex actions like Addo cart or remove card or update card is a little bit confusing. If you get confused a lot, then in my suggestion, don't implement use reducer hook because at the end of the day, have to work on your code and use reducer is just for organizing code. You can leave use reducer hook. It's not compulsory, but many students wants to learn use reducer hook. That's why I add this lesson. Now let's see the solution for this. In our source folder, we create a new folder called reducers, and inside this folder, we create a new file called card reducer dot js. Now inside this file, we create a new function, card reducer, equals to here we get two parameters. Do you know which are they write? First, we get state, or we can call here cart, and second one is action, which is the object we pass in dispatch function. Now inside this function, we have to write switch case. So switch, and here we add action dot type, Cali Brackets. Case for Add to Cart. Column, let's go to the app component, and let's simply cut this logic for stage change before we are calling head to cart API and paste it in the add to cart case. Now to format this code, let me save this good. Now here at the end, we need to simply return updated state. Semove this set card function and we return this updated card. Now let's export this reducer from here. So export default, card reducer. Says the changes, and in our app component at the place of this use date hoop we write use reducer, and first of all, we want here reducer function. So card reducer, nice auto input works. And at the second parameter, we had default value of our card, which is empty array. Now use reducer returns to items, so we can destructure here card and dispatch card. Now, in our head to card function, we call dispatch card function, and inside it, we pass object, and first property is type, which is head to card. Make sure you write the same string as you use in switch case. Now here in our switch case, we don't have this product and quantity. So how can we get that here? Right. Same as we get this type. So in our dispatch function, we pass another property called payload. In this payload, we can send all the external data which we want to send in reducer function. This is the common properties name, type and payload. You can change it if you want to, but make sure you have to use that property name in the reducer function. We pass here object and we want to send product as product and quantity as quantity. Or we can even simplify it like this. Save this file, and in our cart reducer function, here we get cons Cli brackets, product, quantity equals to action dot payload. Save the gangs and take a look. Oh, we get here error. Let me open the console. See, here we get set card function is not defined. So in our app component in our Getcard function, we can't use the set card function. So we need one case for Get card function. So we call dispatch card function and pass its type to Get card. And in the payload, what we want to send write? We want to send object with products to response dot data. Save this file, and in our reducer function, we define another case, cat card, column, and inside this, we simply return action dot payload dot products. Save the changes, and take a look. Again, we get here error. I think still there are SAT card function. See here we are passing set card function in the card context. Save the changes and take a look. See, here we get our card details. So our reducer is working well. Now here we need one more case because if our At to cart API gets error, then we have to also set our card to previous state. So here we call dispatch card function and pass here type to revert card. And in payload, we pass object with card property. Save this and in the reducer function at the bottom, we add another case for revert cart and simply return here action payload dot card. Save this and it will work. Now let's adt case for remove front card function. In this function, we cut this logic till set card. And in our reducer function, we add another case remove from card. And here, we simply past the code. Now at the place of set card, we can add written new card, but here is the one thing. We need here the product ID which users wants to remove. So we can add here action dot payload dot ID. This. And in our app component, here we call dispatch card function and pass here object with type to remove from card and add another property payload to object with ID property. In the cache method, we want to revert the card state. We can simply copy this dispatch card function for revert and paste it inside cache method. Also, let's replace this in all cache method. Good. Now here, we don't need this old card variable, so we can remove it. Now let's set our last case, which is for update card. Here, we can implement two solutions. We can create separate cases or increase the quantity and decrease the quantity. Or we can simply do that in single case. But in these both cases, we get confused a lot. Skip these SA is, or we can simply do this. At the place of this set card function, we simply copy this dispatch card function with a type cat card, which will replace the current card state with the updated card. Here we paste this and replace this response dot data to updated card. Now, duplicate this and we also do the same for decrease. Save the changes and take a look. See, adding, removing and updating all functionality is working well. Now, you have to decide you need use reducer or not to organize your code. In my humble opinion, you can use use reducer hook for little less complex actions, but for more big complex actions, I don't suggest to use use reducer hook. The choice is yours. If you are confused even one to 2%, then don't use use reducer hook for that action. It's completely fine. This is the updated section for the ultimate react course and the next update is about to react query. Stay tuned for these updates. I hope you enjoy this course. Stay tuned for these updates. 186. Section 17 Master React-Query: Welcome to the 17th section of the ultimate Rac course. In this section, we are going to learn the best library for managing and catching the data in react application, which is reac Query. By implementing read query in our project, the performance of our application will increase so much. When I decide to create this react course, to be honest, I don't know about all rea query features. When I ask students for topic suggestion, most requested topic was must add rea query. So then I tried to research on Raquery and truly it's amazed me how useful this library is. If you think the same as me, then let me know in the Q&A section. I love to hear about that. So here is the comparison. I'm showing you both without Raquery and with reaquery how our application improves. So as you can see, reaquery implementation is really good and better for our application. So without wasting your precise time, let's learn the reaquery in a very simple and easy way. 187. What is React Query and Why we need it: Now before we start learning rea query, let's first understand what is rea query and most important, why we need it. So re query is a library which used to manage and cache data of our API request. By using Requeri library, we can easily fetch, update, cache our data, which we get from APIs. Now, here we understand fetch and update, but you might think, what is cache. So cache is a store which can hold the fetch data in memory. It act like a temporary storage for our data which we return from API request. Let me explain you with the example. So in our card Wish project, we are fetching all product list here. Now, these all products data stored in the temporary storage called as case. Now, if we go to another page like Card page, and again, come back to our products page, then we get that data immediately from case. So if we implement cache in our application, then user experience will increase immensely. And this is not just enough. The other features of re aquery is we get request cancellation feature on component mount. Also, we get multiple times retries, which means if our network connection is gone, or for some reason, our request fail, then requery can retry multiple times that request. Also, you can turn off this feature if you want to. It's totally up to you. Next, also we get automatic refresh in the interval of time. Like we can set timer, for example, 2 minutes for automatic refresh. In every 2 minutes, we get data from the server if user is still on that page. Of course, we can implement these features by writing more code, but with requery, we can implement these features in very less code. If you want to improve user experience of your application, then for managing and gaching data from API, we can use Rea query library. I'm seriously in love with this library. Developers think Raquery is complex, but trust me, it is not. It is just a matter of time and practice. So to make Raquery simple, I divide Raquery section into parts. First of all, we will learn all concepts on another project, and then in the next section, we will do exercise practically by implementing those features in our cartwish project. So let's start learning Raquery. 188. Setting up React Query in our Project: Now, let's set up Requeri in our project. So for learning Raquery, we are not going to mess up our Catwish project. Instead of that, we will learn all concepts on our previous routing project, and then after learning all concepts, we will update our Catwish project as exercise. Here, we use our old routing project on which we learn routing and calling API in Section eight and nine. You don't find your project, then don't worry head over to Resources folder and you get this re aquery template, which is the same project. So let's open this project in VS code. Nice. First, we will install all packages with NPM install. Good. Now, let's quickly add rea query in our project. So here in our terminal, we write NPM, I, at the rate, ten SCR query. And if we want to install the exact same version, then write at the rate 0.12 0.2, and hit Enter. Good. Now minimize this terminal and open main dot jsx file. Here, we have to wrap our application with one rea query component, same as we did in Rag Router doom. So here we import. First we need query client from ten Stack Raquery and second, we need query client provider. Now, after our imports, we create a new instance called query client equals to new query client. Now, can you guess with which component we wrap our application with query client provider because that is the one which is remaining. You are smart. Now we simply add here client attribute, and inside this, we pass our instant query client, which we just created here, and that's it. We successfully added rea query in our project. You think you have to remember this process, then don't worry. You can see this process on rea query documentation. Now in the next lesson, we are going to fetch data using Raquery. 189. Fetching Sellers Data: Now, let's fetch data using rea query. So in re query, we have us query hook, which is used to fetch and manage the data from APIs. So here in our seller's component, here we call U Query hook from ten Stack rea query library. Now in this us query hook, we have to pass configuration object with two properties. First one is for query key, which is the unique identifier for our query. Mainly, it is used for caching. So anytime we retrieve a data from the back end like seller's information, that data were stored in the cache with this key, and in the future, it will be accessible via this key. We have to set our key to array, which can have one or more values. Most of the time, first value is a string, which is used to describe the type of data we are storing in the cache. In this case, we want sellers data. So here we can pass like other strings for sellers or we can even pass object like page to one, et cetera. For now, don't worry about that. We will see this in detail in guessing lesson. For now, let's focus on fetching data. Let's remove these other values. Now the second property is query function, which is the function which we use to fetch data from the back end. Note that this function should always return promise that can return data or error. So here we pass error function and here from this use effect, we copy this API client dot Gad method, which is our Axios variable and simply paste it here. Now, you might ask, should we always use Axios for query function? And the answer is no. We can use Patch API or any library for making STTPRquest. Raquery don't care about how we are making STDPRquest. It only cares about managing and caching data, but make sure it should return a data or error, only that's the condition. Now here, we know that this API client dot Get Method will return response object, but we don't want to store the full response object in the cache. We want to only store the real data which we get from the back end. So we add here then method, and in that, we get response, and then we simply return response dot data. And in this data, we get our sellers details simple as that. Now here, we can also implement this logic outside of use query. So at the top, we define function called fat sellers, and here we add our arrow function. And the query function property, we just pass function reference. So at the runtime rea query we call this function. And when this promise will resolve, we get an array of sellers data, and then that array is stored in the cache with this key. How can we access data from this use query hook? This use query will return object of couple of properties like data, error, loading, status, et cetera. So here, we can restructure that object and get here data. With this use query, now we don't need to create the sellers errors and iss loading state variables. We will get all variables from this use query. So we can remove the state variables. Also, we don't need this use effect. And in our JSX, for now, let's comment out this ease loading statement and also error statement. Now, here at the place of these sellers, we can write data dot map, or we can even rename our data object and give it a name sellers. I think that is more accurate. Save the changes, and let's run our application. So in terminal, NPM run DV open this link. Now navigate to the admin page and open seller's page. Here we can see we are getting error. So let's open Console and we can see cannot read properties of undefined. So why does that happen? Because while we don't get data from the back end, by default, our data is set to null. So to solve this, here we have to add question mark, which is optional chaining. Save the changes and take a look. See, here we get our seller's data. Now refresh the page. See, we are almost immediately get our data. This is because of caching. Let me show you that clearly. Click on this sales page, and when we click on sellers page, here we can directly see this data without any delay. This is caching. So with requery implementation, we get auto retries, which means if something happens and our API calls fail, then requery will retry a couple more times. After that, we get auto refresh, so we can set the amount of time and after that time, our query gets auto refresh. The most important feature is caching, which means first time we get data, it's stored in the cache, and then if next time we get the same piece of data, if it's available in cache, then we are not going to the server. Instead of that, we get it directly from the cache and this will improve our application performance tremendously. Now in the next lesson, we will handle errors and loading in rea query. 190. Error Handling & Loading: Now, let's see error handling with Raquery. So as we know, our reaquery returns object. And in that object, we also get error property. So we get here error. Now in our JSX, let's remove comment from this error statement. And at the place of errors, we add error, and inside our emphasis tag, we print error dot message. Now let's make one typo in our EPI and point, save the changes, and take a look. Refresh the page, and in the console, we can see Raquery is retrying multiple times to fetch data from the back end because of its auto retrying feature. And after some time, we get error. Now let's display loading indicator. So as we get error property, we also get ease loading property from our use query hook. And in the JSX, we only need to remove this comment and display our loader. Save the changes and take a look. Here, we can see our loading indicator also. So that's how we handle error and loading in rea query. Now, do you remember in our cartwish project, we have created a similar type of our custom hook, which is used data. But this use query has much more features than our used data hook. So we will do whatever the best thing for our application. Don't get entangle with your own code. As a professional software engineer or web developer, your most important goal is to make your application work better. And for that, we will do whatever needs to do. 191. Creating custom hook with React Query: Now, in our current implementation, we can separate our us query hook from our component. You can use this approach, or you can stick with current implementation. Choice is yours. It totally depends on you. So in our source folder, we create a new folder called hooks, and in that folder, we create a new file called Uellers dot JS. Now, first of all, here we create a function called us sellers error function, and at the end, export default us sellers function. Now, from our seller's component, first we cut our fat seller's function and paste it in our custom hook. Now again, back to seller's component. From here, we cut us query with this configuration object. And in our us sellers file, we simply return here use query. Now let's import API client, remove this typo, and also let's import US query from TNSTekRquery Library. Save the changes. And in the seller's component, here we just call us sellers custom Hook. So now in any other component, if we need to fetch sellers data, we only need to call this use sellers hook. Let's remove this all unwanted imports, save the changes, and take a look. See, now our code looks little bit more clean. 192. Adding React Query DevTools: One of the easiest way to learn how Raquery work is by using Raquery DevTools. Let's add Raquery Dev tools in our application. So open up terminal and write NPM, I at direct ten Sag re aquari DevTools, att 5.13 0.3 and hit Enter. Good, minimize this terminal, and in our main dot GSX file, at the top, we import one component called re aquery DevTools. Now we have to add this component after our app component, Raquery DevTools and make sure we add it within this query client provider component. Otherwise, it won't work, and that's it. Save the changes and take a look. See, at the bottom right corner, we get a beautiful logo. You get another logo, then don't worry. This library changes their button logo many times for fun. Simply click on that and we get React query Dav tool. Here, we get this type of structure. Don't worry. It is pretty simple and useful. Here we can see we get the list of query, which is our seller's API. Click on this. Now at the right side, we can see here we get our query key. After that, we get observers which is the number of components which are using this seller's query. Currently only one component is using this sellers query. Suppose this same query we are using in three components, then observer counts will display three. Next, we have last updated time, which is the last time the query get fetched. Now after that, we have a couple of useful actions like refetch, invalidate, reset, remove trigger load trigger error. So we can trigger loading and see. Here we get our loading indicator. Now let's restore loading, and we trigger error. See, we get our sample error. Now, after our actions, we have data explorer, which is what query returns, and that's our seller's data, and we can also see its properties. Now at the last, we have query explorer. Here we can see all properties and details about our query. Most commonly, we are not using this section, but some properties are useful. Like here we can see our GC time, which means garbage collection time. Or we can say case time is set to 300 K, which is miniseconds value, and it is equals to 5 minutes. So if our component is removed from our screen, which means we have zero observers and when query has zero observers, after 5 minutes that data will remove from cache. Yes we can change these properties, and we will see that in the next lesson. Also, mini tip from here, we can change the theme of our Dev tools. I like dark theme, so I'm selecting dark. 193. Customize our React Query Properties : Currently, in rea queries, we have few default settings which works good in most situations, but we can also customize them for all queries or for an individual query. For example, we can change our GC time value. So let me show you how we can do that. So in our main dot jsx file, here in this query client, we can pass configuration object. In that object, we have property called default options, and we can also set to object, and in that object, we have queries property, which is also object. Now, in this object, we can pass default values for our query properties. So here we pass CT and we can set it to 10 minutes. Here, we have to pass value in milliseconds. So ten into 60 seconds into 100 milliseconds. Or we can directly pass 600 K or we can write here six double zero, underscore zero. In JavaScript, we can add underscore at the place of commas in digits. Save the changes and take a look. In our Dev tools at the bottom, we can see C time is changed to 600 k milliseconds, which is equals to 10 minutes. Now we can also change the number of times our query retries. So if our user connection get lost or we have typo in our query, then rea query retries couple of times. By default, it retry count is set to three, but we can change that from here. Let's say five. Save this file, and in our use seller's hook, we adhere typo in our endpoint, save the changes and take a look, open NetworkTab and refresh the page. Here, first time our query is filled. I think I have to switch this panel to write. Now refresh the page and see here we get request one fail. After that, it will take some time and retry five more times. So total six request gets sent to this query. Now back to VS code, and here we remove our typo. Save this file, and in main file, here, we have also stale time which specify how long our data is considered as fresh. Currently, our stale time is set to zero, which means the moment we get data from the back end, it is treated as old. So if next time we need the same data, reacquery will fetch a new refresh data from the back end. So for demo, let's set it to 6 seconds. Save the changes, and here we get fresh data, which we can see by green color. And after 6 seconds, it will become still means old. Now, as I told you, reacquery automatically re fedge our stale data. So let me tell you in which situations it will get refedge. So first of all, when our user connection is reconnected, then component is mount and last when our application window is refocus. So let me show you this practically. So here in our browser, if you open a new tab and again, come back to our application tab, then our data get refreshed. So open a new tab and back to our application. See, here we get a phrase data, and then it becomes still. In most applications, this auto refash feature is very important. But sometimes if your application don't need that feature, then you can also disable it. So in our query object, we have refedg on reconnect property. We can make it to false. Also, we have refedg on mount and set to false and refetg on window focus, we can also make it false. By default, these three properties values are true, but if needed, we can make this false. Now let me explain to you one scenario. When our data becomes still, requery will try to refetch new data from the server. But at the same time, it will return still data from the cache to our component. With this implementation, we can get our data immediately, but also at the same time, we are requesting the latest data under the hood. Once we have the latest data, Raquery updates our cache and also updated data on our component, which is pretty cool, right? So here, we can change the default properties of all queries. Most of the time, we will not change that because these properties are already good. But sometimes in our application, we have to change these properties for only one query. So how can we do that? Let me show you open seller's hook. And here, in the use query hook, we can pass the same properties like retrte to five, and we can also pass other properties. So that's how we can change the default properties of queries. 194. Exercise for Fetching Data: Now it's time for little exercise. So in our Admin sales page, I want you to fetch data about todos from our JCNPlaceholder API with the help of re aquari. So our API should be GDPs, colon, double forward slash jsnplaceholder.typicod.com slash Tu Doo. This API will return 200 fake todos data. So make custom hook for fetching todos we have to display those sudo title in simple paragraph and also display error and loading indicators. I know you can do that, and after that was the solution. So here is a solution of this exercise. First of all, in our hooks folder, we create a new file called ustdos dot js. Here, we create a new function called ust Dos error function, and at the end, let's simply export default this todos. Now, here before this function, we create a new function called fast Dos, error function. Here we directly return API client dot cat and endpoint, which is slash todos. This expression will return promise, so we use then method, response, and simply return response dot data. Here we are returning response dot data because our JSON placeholder API returning todos in data property. For your API, you have to check your API response and make sure you return those data. Now, let's call our use Query hook from Raquery Library. Here we pass configuration object, and we have to pass here two properties. Can you tell me what are they right? Query key and query function. So queriy to array and pass here todos. After that, query function to pass todos, and we simply return this use query from this hook. User changes and on sales page here in our component, we call STDs Hook, which we just created. And as we know, this hook written object with properties. So we can restructure it here, and we get data, which we can rename Tutu Dos. Also, we get error and ease loading property. Are you noticing how simple it becomes to call a PI? I really love this react query library. What do you think? Now in our JSX, here we change this heading to do page. And for adding multiple elements, we use react fragments. Move these to the end, this to format our code. And after our heading, we add calibracets, todos, question mark dot Map. Here we get single to do object, which has ID, title, completed and user ID. We simply written here paragraph tag and give it a key to Tudot ID. Inside this paragraph, we display Todo title. Also, let's show error and loading indicator. Before this map function, add Cali brackets. I is loading is true, then we return loader component and auto input works at last, we add Cali brackets. If error is available, then we return emphasis tag and display error dot message. The changes and take a look. Move to the sales page and see here we get our todos. Let's check it in query DevTools and see here we get zero per sellers query. This zero is Observer count, and on our page, we have zero component, which is calling the sellers API. Currently in our application, our page has one component, which is calling the query. If we move to seller's page, then we get one observer for sellers query and zero observer for to do Squery. So that's what observers mean. Count of currently rendered components, which uses the query. 195. Understanding Query Params in React Query: In this lesson, we will see how we can pass parameter in our use query hook. We will build something like this. Before our heading, we have one drop down list, which has five values like user one, two, three, four, and five. When we select user one, we get only those todos which are created by user one. Basically, we are going to perform filtering. But here we are getting data from backend and we pass our filter details in query params of our to do API. Let's see how we can do. So before our loading indicator, we had selecteg and inside this, we had option six times. Now, in our first option, here we add nothing in the value, and here we pass select user. Now, after that, we pass value to one, and here we pass user one. Similarly, value to two and user two, three, user three, four, user four, and last five user five. Here we don't need this name and ID attributes, so we can remove it. Save the changes and take a look. See, here we get our dropdown box. Now when we select here user one, we should only get two dose of that users post. We have to handle this dropdown. At the top, we create a new state variable called user ID, set user ID, and as a default value, we set to null. In our select tag, we add change event, and here we get event object error function, and we set user ID to event target dot value. Also, here we get value in string, so we need to convert it into integer. And how can we do that? Right, by wrapping our value in parse int, and here we also pass value to our user ID. Good. Now in this component, are using our custom hook used to do. In that hook, we can pass our user ID state variable as argument. Save this file and let's see what we have to do in our used todos hook. First, we get here user ID as parameter, and here in our API request, we have to pass this user ID with our GAT request. Here, we have to move this function in our use todos function. So we can access user ID in our fair studios function. Now here, we have to pass something like this slash Studios, and in the query parameter, we pass User ID equals to our user ID. Or we can pass object in the second argument and addheParams, which is an object. And here, we simply pass user ID to user ID, or we can remove this. No one last thing to do is we have to change our query key. Currently, we are only passing single string in our query key, but now we are dealing with multiple data in our query. We have to also add that in our query key. So here we pass our user ID. Also, here, many developers like to use hierarchy structure which represents the relationship between our data object. Let me show you what I mean. Here, we start with top level object, which is users. That user has ID, which is user ID. And by this user ID, we can fetch todos. This is the same structure which Bend developers use to define URL of our API. So our API URL can be like this. Users one, which is user ID, slash todos. I think this pattern is more specific. Now, here is the one thing. Here we are passing user ID in this query key, which means whenever the user ID will change, rea query will refresh the data from our API. If we don't add user ID variable here, then our query will run only one time, even if we add that user ID in our params. So this query array is similar to our dependency array in use effect. Save the changes and take a look. Let me zoom out a little bit. Now see currently we have no user selected, so we get here users null todos, and we get all todos. Now if we change user to one, then we only get data of our user one. In our dev tools, we get users B todos. Similarly, we can select other users and for each user reacquery fetch new data. Now we have all data in our cache. If we go to the previous users, we get our data immediately without any loading. This is the beauty of rea query. The only thing I want to fix is for null value, we will change our query key. Back to VS code, and here we pass condition if user ID is available, then we return this key array, else we return array with only string to do because for null user, fetching all to dos without any filter. Save the changes and take a look. Refresh the page and see here we get only two dos and if we select user one, then we get our query key with users user ID and todos. Now here we have one little issue. So if we again back to null user ID, then here we don't get our data. Why? Let's check that in NetworkTab. Repress the page. First of all, here we get all todos. Then we select user one, and here we get todos request with the user ID one. Now let's select again, select user and see here we get user ID to not a number. And that's the issue. So to solve this issue, we have to pass condition for this user ID parameter. So to simplify this, I create here new variable called params, which we pass as Params object. Now, after that, we add condition. If userID is available, then we set params dot UserID to our user ID. I user ID is null or undefined, then we don't add user ID parameter. We can simply pass here params to params, or we can remove these one params. Save the changes and take a look, repress the page, select user one, here we get user B data, then select user and see, here we get all to dos. That's how we pass query parameters in rea Query. 196. Pagination in React Query: Now, in our to do list, we are fetching 200 todos in single request, but that will increase the load. Previously, in our cartwig application, we have same situation. Do you remember what we have done for reducing this load? Right, we use pagination or infinite scrolling feature. First, we will see the pagination query in this lesson, and then we will also see how to apply infinite scrolling query. Don't worry about that. First of all, let's remove this filtering because I don't want to make this complicated. So we remove this user ID state variable from here. Also, remove the select tag with these options. Good. Now for pagination, we need page state, which we can change or handle by our page buttons. So here we create a new state variable called page set page, and as the default value, we pass here one. Now, let's add previous and next buttons for pagination, for simplicity. So after our Tudos map, we add button and pass here previous and another button or next. Now for previous button, we can add disable attribute, which will disable if page is equals to one. As we pass on click event and inside it, arrow function, and set page to page minus one. Now for next button, we pass disable to here, we pass page into page size. Page size is the number of data which we want to display in single page. And we know this query has 200 to do. So we pass here greater than 200. Now you might say, here we know we have 200 to do. What if we don't know the total number of products in our application? So in this situation, you have to tell Backend developer to also send a number of total products with your API data. We already see that in our cartwh project, right. Now here we pass click event, and inside it, we set page two page plus one. Good. Now here, we create simple variable called page size equals to, let's say ten. Now in our used to do at the place of this user ID, we add page and page size. Now imagine in this feature, we also want to add filter or shot by features. Then we have to add multiple values in this function. So instead of that, we can pass all values in single object. So add object and pass page and page size. Okay? This file and in our used to do so at the place of this user ID, we get our query object. Let's also remove these params, and if condition, we can directly pass perams here. Now, in our query params, we add object, and inside this, we have to pass two properties, underscore limit, and underscore start. These parameters depends on your API. So here for limit, we pass our query dot pay size, and for start, we have to pass the starting point for our todos. So here we pass query dot page, minus one, multiply by our query dot page size. Now, if our page is set to one, then one minus one, which is zero and multiply by ten, which is also zero. So our starting point is zero. So we get post 1-10. Then for page two, our starting point will be one into ten, which is ten. So we get post 11-20 simple as that. Now, let's change our query key here. We don't need this condition. We pass array with string to do, and after that, we directly pass here or query object. So if something changes in this query object, reacquery will fetch new data from API. Save the changes and take a. See, here we get only ten data, and our previous button is disabled. Now, click on next, and we get next ten data. And also, if we go back to the previous page, then we get data without loading because it's stored in cache. Now, one little update we want to do is when we click on next, our previous and next button, move up and then down. So to fix this here in use query, add here one property called placeholder data here, we have to add one function reference, which is keep previous data. Make sure it is from ten Stag react query library. Here, we can see it is imported from our rea query library and that's it. While we are fetching new data, we still see the previous data, and if we get new data, after that, previous data will go away. The changes and take a look. Click on next and see while our data is patching, our previous to dos are still here, and after completing the request, we get our new data. So you can see how simple and easy it is to add pagination using rea Query. 197. Infinite Scrolling in React Query: Now let's see how we can fetch infinite query using rea query. So we are going to add load more button at the bottom, and when we click on that, we get our new data. In real world application, we will load our data when we reach to the bottom of our page. We will see that in our exercise part. For now, let's implement this. First of all, for infinite scrolling, we have to replace our use query hook to the use infinite query hook. Save this. Now here is one thing. When we are using use Infinite query hook, we don't need to pass page straight Iquery object. Use infinite query does that automatically. Here we can remove this and also remove this page from query object. Now you might think, how can we count or page numbers? Don't worry. It is really very simple. So for counting the page numbers, we have one function in our use infinite query called as Get next page perm. Here, we have to pass callback function, and this function has two parameters. Last page, which is the last page array of our to dos and second parameter is all pages, which is the two dimensional array, or we can say two D array. Something look like this. We have array and inside this array we have each page data in sequence. Don't worry about that. When we print our array, you will understand that. Just remember that these all pages is the array of all todos. Now, here in this function, we have to return next page number. How can we find that? As I told you before, the all pages has all data about our todos. If we loaded two pages, then our all pages data look like this. So here we can do something like this. We return all pages dot length N plus one, which is our next page number. Now, what if we scroll to that page which is not available? Then we don't need to pass next page number. So when we pass page number, which is not exist in JSON placeholder API, it will return empty array. So we pass here condition I last page, which is our last page data dot length greater than zero, if it is true, then we return next page, else, we return null, simple as that. Now we just need to pass page number in our past dos function. Rea query will pass our page number in our query function parameters. Here, we destructure object and get here page param. And pass it at the place of the query dot page. Also, for default value, we pass your page per um to one. In simple words, whatever we return from this next page perm function, we will get that value in our page per um. Save changes, and in our sales component at the bottom, we can remove both buttons, and here we add a new button pload more. Let's add on click event for this button. And here, we have to pass next page function, which we get from our use infinite query. And at the bottom, in our on click event, we simply add fetch next page function. In our Catwig project, when we reach at the bottom of our page, we can simply call this fetch next page function. Save the changes and take a here we get error. So let's inspect this and in the console, here we get todos dot map is not a function. Let's print what we get in our data. So console dot log data and we remove these todos from rename. Save the changes, and in our console, scroll up. We are getting undefined. I think we have to comment out map method. Save the changes and see we get the data. Here, this data is object which has two properties, page params and pages. In these pages, we get array of our ten todos. So in our JSX, before our todos dot map, we had data question mark, dot pages dot map. Here we get each page data arrow function. And here, we have to return another map method because each page is array of to dos. So here we add react fragments, and inside this, we can move this map method. And replace this todos with our page. Say the changes and take a look. See, here we get our data. Now click on Load More button, and we get another todos, so it's working. But in our console, we get here error, which is list should have unique key prop. So here in our react fragment, we have to pass key props. So for that, this react fragment syntax will not work. We have to add react dot fragment. And key to here, we get index and pass it here. Say the engines and take a look. See, error is gone. Now when we are fetching data, we can disable our button. Use Infinite query has one more property for that, which is fetching next page. As we get as next page at the bottom, in our button, we add disable attribute and pass here, es patching next page. Also, we can change our button text so we can pass here condition. If epatching next page is true, then we return loading dot, dot, dot, else we show load more. Also, we wrap our button with curly brackets and add here I as next page is true, only then we display this load more button. This property return, our query has next page or not. Say the anges and take a look, refresh the page and click on Load More. See, here we get our loading text, so it's working. 198. useMutation hook for Mutation: Till now, we have seen how we can fetch data using rea query. Now let's see how we can mutate, which means add, update or delete data in our application using Raquery. First of all, let's close all files and open sellers component. And in this lesson, we will perform add seller functionality with rea query. For mutation, we have one hook which is use mutation, same as we have use query and inside this function, we pass our configuration object. In our use query hook, we have query function. But in use mutation, we have mutation function. And here, what we will pass, right, we pass our function, which we'll call API and return data. So we pass arrow function and we add api client dot post and 0.2 slash users dot then method response, and we simply return response dot data. Currently, we are not passing here new seller's object. We will see that in just a second. Now you might ask, how can we call this API, which we just define? For that, this use mutation function returns one object, we store that in variable called add seller mutation. This object has one method called mutate. By using that mutate function, we can call the API. Where we want to call this API in the ad seller function. First of all, here we remove these set sellers and also remove this API request. We don't need and here we just add add seller mutation dot mutate function. This will call our this mutation function. Now we can pass our new seller's object, which we created previously. See here. And as we pass object in muted function, here, we get that parameter in our mutation function and pass it after our endpoint. Save the changes and take a look. Go to the seller's page and open Network tab. Write new seller and click on Add seller. See, here we get New Post request ID with our name. Now, as we done previously, we can add our new sellers in this list. So there are two ways to updating our list. First one, we can directly update our cache. And second, we can invalid our old cache, and then we can refetch our data from the server. Here in this situation, we can't use this second way because JCNPlaceholder will not add our data in actual server. It is just for tasting, but don't worry. I will show you both way here. Let's first see this second way, and after that, we will write our code for directly updating cache. So here in our use mutation hook, we have another method called on success, which will run if our API request completed successfully. Also, we have on error property, which will run if any error occur in this mutation. Here we can display toast notification for errors. For now, we don't want so back to on success and we pass Callback function, and here we get two parameters. First parameter will return our seller's object from back end. We can call it as saved seller and also we get the new seller's object, which we just sent with our API. And inside this function, we first see how we can invalid our previous seller's query. For that, at the top, we call us query client from rea Query. And store that in variable called query client. This query client is same as our main dot JSX file, this client object. Now in our on success function, we add query client dot Invalidate queries and inside this, we have to pass Object pass here query key to our sellers. Whichever query has this key start with sellers that all queries are set as invalid, and that's why rea query will refresh that queries. Save the changes and take a look, write our seller's name here and add seller. See, our query with seller's key are getting fest. You can see that by last updated value. See, again, add seller and here this time gets updated. Here we don't see anything change in our list because Jon placeholder, not really saving our new sellers in the server. If they will store that, then we get that new seller here. Now, let's see another way, which is by directly updating the cache. So for that, we comment out this method and add comment for method two. And right here, query client dot set query data. At the first argument, we have to pass query key, which is sellers. And the second parameter is the data function. So we get here our sellers, which is the array of current sellers list, error function, and we return array. Now, first, we add our saved seller object, and after that, we add spread operator sellers, save the changes and take a look. Enter seller's name and click on ad. See, here we get our new seller. That's how we mutate our data in react Query. Let's quickly recap about mutation. As we call us query hook for mutation, we call use mutation hook and inside object, we pass mutation function which takes function with the API call. After that, we have success property which will run after our mutation completes successfully. Here we update our cache data with this query client dot set query data. And at the bottom, for calling this mutation, we add Ed seller mutation dot mutate function. Simple as that. If you're a little confused, then don't worry from this exercise, you will understand this concept. So here is a little exercise for you. How to apply use mutation method for this delete seller and update seller functionality. Result should stay the same as we are deleting and updating the seller's list. Try to solve that. And if you need, then you can rewatch this lesson. I will see you in the next lesson. 199. Delete and Update Sellers: I hope you try to solve this exercise. Now let's see the solution really quick. First of all, I will move this use TD hook at the top. Good. Now after our Ads error mutation, we call again use mutation and pass her configuration object mutation function to arrow function. Now from the bottom, we got this API client from the delayed function and paste it here. Here we don't need this sketch method, so we can remove this. And here we add then method, response, and return response data. Now we get this ID here from this parameter. Next, we add on success method and pass here callback function, and here we get our deleted seller data, arrow function, and write query client dot set query data. At the first argument, we pass our key sellers at the second argument, we pass our updater function. So here we get our sellers arrow function, and we return here sellers dot filter. Here we get single seller, arrow function, as ID, not equals to our selected seller ID. So right here, deleted seller dot ID, but here is a one issue. Sun placeholder don't return anything when we delete user. Let me show you this live. So for calling this API, let's store this mutation object in variable called delete seller mutation. And in our delete seller function, let's remove our previous code. Here, we call it delete seller mutation dot muted function. And inside this, we pass our ID, save the changes, and take a look, open Network tab, and here we delete the seller. See, we get here delete request, but our list is not updated because in the server response, we don't get anything. Now, how can we solve that? It's really simple. We can also pass on success method in our this mutate function. So after our first argument, we pass configuration object here, and simply cut our on success method from use mutation hook. And paste it in this object. Now we don't need here deleted seller parameter, and at the place of this deleteller dot ID, we just pass ID. Say the changes and take a look. Click on delete and our seller gets deleted from here. Now let's see how we can update seller. After our Delete mutation, we again call US mutation Hook. Pass here configuration object, mutation function to here, we get updated seller object, which we pass from our update sellers function, error function. Let's get this EPA client with patch method. And paste it here. Also, we remove this sketch method and add the method because this API will return our updated seller data. So response and return response dot data. Now, at the place of this seller dot ID, we add updated seller dot ID. Now here we are getting data from server, so we can pass here on success method. Here we get our updated seller object, which we get from server, arrow function, and inside this function, we add query client dot set query data. First, we add Query key, which is set to sellers, and after that, updated function, we get sellers data, arrow function. Here, we have to return updated array. For that, from bottom, we can cut the seller's dot map method and simply paste it here. And in our condition, we change seller dot ID to updated seller dot ID. Now for calling our Update mutation, we store this use mutation in variable called Update seller mutation. And at the bottom, we can remove the set sellers and simply call here, Update seller mutation dot mutate and pass here, Updated Seller Object. Say the changes and take a look, click on Update button and see we get here updated seller. Now you understand how we can use use mutation hook to mutate our data. It's really simple. Just we need to practice. 200. Handling Error in Mutation: Now let's see how we can handle errors in mutation. In our add mutation object, we have one method called on error. Here, we get our error object, which we get from API and inside this function, we can also write the logic for showing toast notifications. For now, let's simply Consult log this error object. Now let's make here one typo in our endpoint. Use NGs and take a look. Open up Console, write here seller's name and edit. See, here we get Axios error. This error has many properties like CF, message, request, et cetera. For now, we just need this message. So back to VS code and here at the place of console dot log, we can write Alert function and simply pass here error dot message. Hangs and see, here we get error alert. Beautiful. Now let me show you how we can also display error in our page. It is really simple. As we know, all use mutation hooks returns object with mutate and bunch of properties. Inside these, we also get error, which is the same object as this error object. From here, we can comment out this on error method, and at the bottom, duplicate this condition and change this to add seller mutation dot error is available. Only then print here, add seller mutation dot error dot Message. Save the changes and take a and see here we get our error. That's how we display error for mutation. Now let's remove this typo, we successfully taste our application. Now in the next lesson, we will display our progress during mutations. 201. Showing progress during mutations: Now, many times our mutation is running in the background and it can take little time. So at that time, we can display some kind of loader or spinner to indicate mutation in progress. So for that, use mutation returns one property called Es pending. And by using this property, we can display loader. This E pending work the same as our Ese loading state, which we created in our use data custom hook. Remember, in our ad seller button at the place of this ad seller, we pass condition. If adseller mutation is pending is true, then we return adding seller, else, the default value add seller. So we can disable our Add button by disabled attribute and simply pass here at seller mutation dot E pending. So if it is true, then our button will disable, save the changes and take a look. Write seller name and add it. See here we get adding seller and also our button gets disabled. You can see how simple and useful Raquery is. I can't imagine I was not going to add Requeri in this course. But thank God I add it. It will help you a lot. And also, thank you so much for requesting reaquery. I also learned a lot from this. 202. Optimistic update in React Query: Now currently in our implementation, first we are making API request and then mutating data on our page, which is called as pessimistic approach. But we can also apply here optimistic approach, which basically means we mutate our data first, and then we will call our API for that mutation. Previously, we already seen this approach, right? So let's implement this approach in rea query. So in our ad seller mutation here in our use mutation hoop we have one more method called on mutate. Here we pass callback function. This function will run before this mutation function will run, and that's exactly what we want. Let's verify this. So here at the first parameter, we get our data, which we are sending to the server, which is this new seller. And inside this function, we simply consult dot log on mutate new seller. And after that, we simply trigger alert with on mutation message. Save the changes and take a look. Open Network tab, press the page, we name here and click on at seller. See, first we get Alert, and if we click on Okay, then we get post request. So it's clear that this muted method will run before our mutation function. And also in our console, we can see here we get our new seller data. So in this function, we have to add our new seller in our seller's data. Let's remove this code. And simply update our client data. So we can move this set query data in our muted method and change this saved seller to new seller, and that's it. Save the changes and take a look right here name and click on add seller. See, we immediately get our new seller data, and then API is calling. Now we have to only handle on success and on error function. In our on success function, we will replace our new seller object, which we just added in muted method. We replace that with the saved seller object, which we are getting from the server. So we write query client dot set query data, pass your key to sellers, and for update function, we get here sellers, arrow function. We pass sellers question mark dot map, seller arrow function, and here we pass simple condition. If the single seller is equals to our new seller, then we return saved seller, else we return that seller as it is. Now, here, this new seller is this new seller object, which we pass in our ad seller function. And we are done here. Now, let's handle on error function because if something went wrong, then we have to restore our data to its previous state. We have seen that in our calling API section. Remember, at that time, what we have done in then method, we are doing same in this on success method. And what we have done in our cache method, we are doing the same in this on error method. Our syntax is changed, but our logic is same as before. And that's why first I explain new logic, and then we are implementing this logic using react query library. So let's handle on error method and pass here callback function. In this callback, first we get error object, then at the second parameter, we get a new seller, and at last, we get contexts. Now you might ask text. So in this context, we get whatever we return from this on muted function. So the logic is we will return our previous seller's list from this on muted function, and then we can get that list in our context. Just see this and your out will clear. So here, before our set query data, we write query client dot Get query data. And inside this, we pass our key, which is sellers. Now, let's store this data in variable called previous sellers. And at the end, we will return the previous sellers in object. Here, we can also simplify. And at the bottom, in our on error function, in this context, we get this object with previous sellers property. So first, we check if Context is false, then we return from this function. And if Context is available, then we can run query client dot set query data pass here key sellers and simply pass here contexts dot previous sellers. Now, let's verify this works or not. So for error, we make here one typo in our endpoint, S the changes and take a look. Write name and click on add seller. First, name is added, then we're getting error and our list is set to previous state. So it's working pretty well. Now let's recap this approach so you can understand it better. First of all, we add on muted function, which runs before our mutation function, and we set our new data directly in our list. After that, we have to handle on success and on error methods. If our API call is successfully ended, then we will replace our new data object with the save data which we get from server. And if we get error in our API call, then we have to restore our list to previous state. For getting the previous list, we get our previous data in this muted function before mutating and simply return it in the object. We can also return directly previous data without object, and then in our on error, we have to write contexts, and that will create confusion. So it's better to return object from on muted, and that's it. We successfully implement optimistic approach. 203. Custom hook for AddSellers Mutation: Now, currently, in our implementation, we store all our mutation logic in this single component, which can be hard to maintain in the future. So we can store this logic in separate hook, same as we created use sellers. If you are okay with this implementation, then you don't need to do this. But in my suggestion, it's better to write clean code. In our Hooks folder, first, we create a new folder called sellers, and inside these, we will add all our hooks related to sellers. So we move these use sellers inside Sellers folder. Good. Now, let's create a new file called used seller dot js. First of all, let's create a new function called use add seller error function. And at the bottom, simply export default, this use add seller. Now back to our seller's component, copy this query client and also copy this add seller mutation from here and paste it in our use add seller hook. And here at the place of storing this mutation in variable, we can simply return it from here. Now let's import line by line some hooks and methods which we need in this code. So first, we need use query client, so we import it from rea query. Also, we need this use mutation hook. After that, we need IEI client, which is our Axios and also I forgot to remove this typo from here. And that's it. Our sEDsellerHok is ready. Save this file and in the seller's component at the place of this use mutation hook, we can call use Ed seller. You can see now our code looks clean. But we have this delete mutation and update mutation in this component. We can also separate them, but I'm giving you that as an exercise. Make separate hooks for use delete seller and use update seller. I'm not showing you this solution because it's too easy. So this is how our component looks after separating mutation from our component. See this looks more clean and easy to maintain. 204. Section 18 Improving website performance with React Query: Welcome to the 18th section of the ultimate react course. Now in this section, we will implement reac Query in our final cartridge project. So as I told you previously, first, I will give you the exercise at the beginning of each lesson, and you have to solve that exercise with your hundred percent. You stuck somewhere or you complete the exercise, only then see the solution. But first, you have to try your best to solve it. Don't worry. I will not give you something new. You already learned those react query concepts in previous section. Also by this section, I will show you how you can add rea query in existing react project without major difficulty. Updating the project is one thing you have to do in your professional or freelance career. So are you excited for improving your project? Let's get started. 205. Do you really need React Query: Before we start updating our react project, first and foremost, you need to ask yourself, do we need this reacquery or not? Because if your application has not much data fetching features from API, then adding Requery is pointless. It will only increase the load on your application. One of my friend had Requery in one little project, which has only two small API calls, like five paragraph data. Do you think about him? Does he make good decisions? Obviously not, right? So here are our three projects. Which projects do you think don't need this reacquiry? Right. Our first project, TAs track, don't need this reacquiry. Now our second project, which is movie Maniac, it has three API calls. Should we add reaquery in it? Yes, we can add requery in this project because this website main focus is on API data. If users don't get movie data quickly, then they will close the website immediately. And as our main focus is API data, we need reaquery even if we have three API calls. So we can add requery in our movie maniac project. And I don't need to ask you about Project three because it also has many fetching features. So that's how you have to think about your react project. Also, in this section, we will only update our Project three not Project two. First of all, in our cartwih project, we replace all fetching logic with use query, and then we will implement rea query for mutation also. Now, first of all, I have to clear one thing is that apply entire library on existing project is little confusing because we have to first be clear about our previous code, and then we have to add new library. And that's why I teach rea query library first with our simple routing project. If you properly understand reaquery in previous section, then now you are at that level to implement it in our cartwis project without taking any stress. Don't worry. I will try to simplify all processes which will help you a lot. So let's start implementing Raquery in our project. 206. Setting up React Query: Now, before we start using rea query, first, we need to set up rea Query in our cartridge application. You have to open your cartridge project, or if you ruin your code, then you get the same code as mine in the resources folder, section code. And in that Section 16, finished folder. So you can follow along with me. But make sure you change the base URL of your back end in the config file. Now here in this section at the beginning of each lesson, I will give you step by step approach for complete all lessons as exercise. So step number one, install reaquery in our project, and step number two, add reaquary Dao tools in our project. You can take all these steps as exercise task. So let's start with step number one, setting up re aquery in our project. So open up terminal and write NPM, I, addict, ten SAC, slash reac Query, adt 5.12 0.2, and also we install query DevTools, so space, addit tenga query DevTools, at date 5.13 0.3. And hit Enter. Good. Now, do you remember in which file we configure re query? We have to add Requeri in our main dot JSX file. Here at the top, we import query client from Ten Stack rea Query and we also need query client provider. Also, we import rea Query DevTools from re query DevTools. Now, after our imports, we create a new instance called query client equals to new query client. Now we have to simply wrap our app component with query client provider. Add here query client provider and move this closing component after our app component, and simply we pass here client to query client. And for adding DevTools here after app component, we simply add react query DevTools component. Saves the changes, and let me run my application using NPM run Dev. Open the link and see. Here we get query DevTools. Here, we successfully set up Raquery in our project. 207. Fetching Data using useQuery: Now, currently in our application, we are fetching most of our data using use data custom hook. But in the use data hook, we are manually managing data error and ease loading property. And we know that if we use use query, then we don't need to manage these properties. Step number one is we will use use query hook in our use data hook and step number two, we will update all components in which we use use data hook. First, let's update our use data hook. First of all, we will remove these three state variables and remove this use effect hook and let's remove this return statement. We will start from scratch. As we done in previous section, here we return use query hook from our function. Now, do you remember what we will add inside this use query? Right, we add object with two properties. First one is query key, and how can we get that query key from the parameter. So here, at last, we can get query key. Now here, we can pass this query key or we can remove it. But for better understanding, I'm keeping this as it is. Now, we add query function, and here we have to create a new function for calling all patch APIs. Before our return, we create a new function called fetch function, arrow function, and we simply return here API client dot Get method. Here what we will add, right, we add endpoint, which we will get from our components. Now, after that, if we want to add some config, then we can also add our custom config here, same as we did previously, we know that this will return a promise, so we add then method, and here we get response and we simply return response dot data. We can simply pass this function, query function. Make sure you don't call this function here, we have to pass reference. Now, for our fetch query, we can set still time to 10 minutes for all our fetch query, which means after we get our data from backend, will stay fresh for 10 minutes, but we can't set it globally because in our ecommerce application, we need to get card details very quick. User can sit for 10 minutes or check its card. Do you understand the situation? So for each query, we can set different still time by using parameter. So here we add still time and by default, we pass here 5 minutes, which is 300 K. And at the place of 600 K, we add steel time parameter. And if we don't have any custom configure, then this custom config can give us error. So we can pass empty object as its default value. Also, let's remove this depth parameter, and at the top, we remove this first input line. We don't need it, and that's it. Save the changes, and here our first step is done. Now, if we check our application, it crashed because when we call used data hook in our components, we didn't pass query key. Don't worry, we will fix it. So we need to update all our components which are using used data hook. Now you might have question. How can we find in which components we are using used data? It will take a lot of time. Don't worry. I have one rig. Here in our explorer panel, we have this search icon. And here, we can search for our function or variable, which we want to find in our project. So here we write use data, and it will show all used data words. But here, you can see it is showing input lines and also function line. So to filter it more, we can add here opening parenthesis and see our list gets narrowed down. Do you like this trick? I hope you like it. Use it a lot when I'm working on big projects. Now, first, we click on our first line, which is in featured product file and C, it will open that file with highlighted our use data. So here we add null in second parameter because we don't have custom gunfig and after that, we pass our query key, which is array products and featured. And still time to 10 hours because we don't need here fresh data every time. Feature products updates after 24 hours, and that's it. Now, let's check this is working or not. Say the changes and take a look. See, here we are getting our featured products. So our used data is working properly. Now let's update our second component from search, which is our My Order page. Same. Here we pass null for custom config enquiry key to my orders and still time to 1 minute because it's necessary. So one into 60 into 1,000, and that's it. Save this file. Now next, we have product list, but we don't touch it because for that, we have to use infinite query. We will skip this. After that, we have products side bar and here we add null for config query key two categories and still time to 24 hours, 24 into 60 minutes into 60 seconds into 100 milliseconds. Reason we addhe still time to 24 hours because it is also rare that ecommerce application updates its products categories. Here you can change still time as your application requirements. It's totally depends on you. Save this for last page, which is single product page, add custom Gun fake to null, query key to products, comma. Here we add product ID, and we live still time to its default value. Save the changes and take a look. See our application works, and I'm amazed were also getting here products data, but infinite query feature will not work. So let's check our product list component. Oh, see, here we are passing dependency array, and our use data hook gets that Squery key, and that's why it is working for past data. But we have to update here with use in finite query. Don't worry. It is also very simple. 208. Implementing Infinite Query: Now, let's implement Infinite Query feature for our product list. Step number one, we will create a new hook for use Infinite query, and step number two, we will update our product list component. Let's start with step number one. So for that, in our Hooks folder, we create a new file called us proroductlst dot gs. Here we create a function called use Products list with arrow function. And at the end, we simply export default, use products list. Now, do you remember what we will return from infinite query? Right, we return here, use infinite query. Now inside this, we add object with couple of properties. So first one is query key, which is for now, let's keep it as products. Now query function. Here, we have to create a function for calling API. So const fresh products equals to arrow function, and we return simply pi client dot Get 0.2 slash products. And here, we have to pass page number and categories, which we pass from our product list component. See, this object has all parameters, so we can directly add that as config. In our use product list function, we get that object as let's say query, and we simply add that after our endpoint. Do you remember we did the same in our previous lesson. Now, let's add this query object in our query key also. Here, this expression returns promise. So we add then method and simply response arrow function, response dot data. Now, let's pass this function reference in our query function. After query function, we add one more property called Get next page param. Can you tell me why we need this property? Right? Basically, this function mans the pages count and phase data accordingly. So here, we have to pass function, which has two parameters, last page, which is the last page data, and second parameter is all pages, which is the array of our all pages. And here we simply return condition if last page dot length greater than zero, which means our last page has data, and if it is true, then we increase page, which is all pages dot length plus one, else we return null. Now, as we know, whatever we return from this function, we will get that object in our query function. So here we get that object and destructure it here and get here page param, and as default value, we pass here one. Now we have to add this page pum in our query object, which we will pass from our component. Here, we can see we are passing page property with our page number. So we have to do the same here. First of all, at the place of this query object, we add object, and first, we destructure our query object, and at the end, we add page to this page peram and that's it. Save changes, and let's call this hook in our products list component. So here at the place of use data, we call use products list. Now here, we don't need to pass endpoint. Only we will pass our params. So I'm cutting the params object and remove all things inside our function and simply paste it here. Now, here, we don't need this page parameter because we already had that logic in Gt next page params, and also we remove this paseed variable from the top. Let's check our component is working or not. Can you guess? Right? It will not work. Save the engines and take a look. Good is a product page, and our app gets crashed. Let's open Console and see here we get error. Set page is not defined. So at the bottom, we remove this set page function. And what we will add here for getting the next page data. Right, we need fetch next page, which we get from use infinite query. And we also remove this use effect hook, which will set our piece to one. Now at the bottom, in our use effect, we will call this fetch next page function. The changes and take a look. See here our error is gone, but still we don't get our data, so we are progressing. Now here, we are getting the same error as we get in our previous section. So let's simply const dot log our data. See the changes and take a look. See, here we are getting data in object with two properties, page beams, which is the undefined. Second, we have pages that has object, and inside this object, we have a couple of properties, current page, post per page, products, et cetera. Previously, in the pages, we are only getting to doce array. Remember, these properties are entirely up to back end. So in our GSX, before our data dot products, we add Ci brackets, and here we at data dot pages dot MAP. Inside these, we get single page, which is our object. So here we return react fragments, and inside these, we simply move our map method, and at the place of data dot products, we add page dot products. Now, as we know, we have to add key property in our react fragment. So we adhere react dot fragment. Also close this react dot fragment and simply adhere key, which is index. And we pass it in key to index. Let's see this is working or not. Save the changes and take a look. Still, we are not getting our data. Here we are getting can't read pages. So in our file, we have to pass data question mark dot pages. Save this and see here we are getting page is not defined in 43 line. So let's check this. See, here we have page. So let's remove this condition, save the changes and take a look. We don't get any error, and we also don't get any data. Now, I think it's the issue in our method. I think we are not getting data because we are displaying here shorted products, but that is also needed for shorting. Maybe we are doing something wrong in shorting. Let's verify this. So here in our use effect, oh, here we are checking wrong condition. So we can remove this data dot products condition and add here data dot pages. And also, here we want to get all products. So here is our data, which is the array of objects. And in that object, we have products property, which has ten products array. Now the question is how we can get all products simply by using flatMap method. So here, at data dot Pages, which is array dot flatMap method. And here we get each page. And we simply return here page dot products. By using this flatMap method, we don't get array of arrays. All our products will add in single array. Now, as we are directly displaying Short products, so we can move this outside of our map method, and we don't even need this data dot pages dot map Loop. Let's also remove this pagination component. It will making our code little messy. Save the changes and take a look. See, now here we get our data. Let's try to change sorting. See it is also working. Now let's check infinite scrolling feature and it is not working. So here I think we did something wrong fundamentally because our page is not changing to two, which means we may some mistake in our use infinite query hook. Yeah, we make such a big mistake. Let me explain to you. This is very interesting. So as we know, this last page is the data which we get last from our back end. Here, we treat this last page as array, but as we know, we are getting object from our API call. Let me show you. So here we add console dot log, last page, and add here last page. The changes and take a look. Here, we can see last page is not an array. It is object which we are getting from back end. Here we get current page and total page is property. So we can simply return here condition like if last page dot current page is less than last page dot total pages. If it is true, then we increase our page count, which is last page, dot current page plus one, else we return null. The changes and take a look. Why I'm getting here eight products only. I think our parameter is not passing properly. Let me check. Here I forgot to add Perms property. We wrap our object with curly brackets and add here Perms property and pass it here. Save the engines and take a look. Let's close the console. See. Finally, we get our infinite query. I intentionally make these mistakes to show you which error might happen in your project. So you can learn from these mistakes when you implement use infinite query. First, you check the last page property and then return next page number according to that. Now we can make this even better by displaying card skeletons while fetching more data. So in our use products list hook, we don't want this is loading property. We simply get here is patching property, and also we get as next page. Now here in our handle scroll function at the place of I loading, we add I fetching, and also we add and then as next page. Only then we fetch next page. Also in the dependency array, we change it to his fetching, and at the bottom, here we change is loading to e fetching. Usage Gs and take a. See now our infinite scrolling feature working better. So you can see how we implement requery for fetching infinite data in existing project. I think this video goes little long, so you can take five to 10 minutes break, drink little water, or play some music, and then continue this section. See you in the next lesson. 209. Should we add caching in AutoSuggestions: Now currently, if in our project, we want to know which facing API is still remain, then what we will do right, we search here. So we search api client dot Get Method. See here we get three files. First one is used data, which we updated. Next, we have card services, which we will see in the next lesson, and at last, we have product services file in which we have API for suggestions. Now, in my humble opinion, adding gaching in search query is not necessary because many few people like to search for same products again and again. Another thing is the reason to add caching in our application is we want to send little less request to the server. And if we are adding caching in our search auto suggestion, we can't delay this suggestion request because if we use us Query for this query, then we have to call Squery in our component. We can't call it use effect because rea query don't allow us to do that. Have the code implementation if you want to add us query in this component, but in my opinion, it will increase the load on our server. So that's why I decide to not use us Query for auto suggestions. 210. Updating getCart Query: Now let's update our last fetching request, which is Get card request. For Gecard API, we use our used data hook. In our app component, here we call use data and we pass endpoint as first argument, which is card null for configuration object, and at last, we add query key, which is card and that's it. We can see how useful is this used data hook. Now as we know, this will return our data. So we destructure here and get our data and rename it as card data. Now here, as we apply use reducer hook, we have to do something like this. We call here UIpecHok and at first, callback function, and second one is dependency array, and add here card data. Now inside this callback function, we add condition if card data is not null, available. Then we set data in our CAT variable using dispatch method. So from bottom, we simply cut this dispatch method from Get card function, and also remove this whole function. We don't need it. Now, paste this dispatch function in our UIfectHok and at the place of response dot data, what we will add, we add card data. Now at the bottom, we have this use effect hook. Let's move it at the top after our use effect hook. This hook is for refetching the card data. But now we don't have Get card function. What we will do simple. We have one function in US query, which is re fetch and at the place of Gcard we call this refetchFunction. Save the changes and take a look. Here we need to log in with our account to get card data. See here we get our card data. Now from our card services file, we remove this Get card function. We don't need it. And in our app component, we will also remove Get card API input. Otherwise, it will give us error. So here we are done with all updates for fetching data. 211. Mutation for Add to Cart: Now, let's start using use mutations for mutations. So in our app component, we have three mutations. First one is head to cart. Second, we have removed from cart and last, we have update cart. So let's start with first one head to cart. We did in previous section, we will create separate hook for each mutations. In our hooks folder, we create a new folder called CAT and inside this folder, we create a new file called used to cart dot js. Now, let's create a function called use ad to cart, arrow function, and after that, we export default this function. Good. Now from this function, we return use mutation hook. And inside these, we have to pass configuration object. Now, first property is S V know mutation function. And here, we have to simply return our head to card API, which we already have in Card Services file. See, here we are returning directly promise. So we can add here dot then method and simply add response and response dot data. Or we can simply cut this API from here and also remove this function. Now in our use at to cut hook, we simply return this API. But here, we have to get parameter in our mutation function for this ID and quantity. Here, also, we have to wrap our parameters in object. I will explain to you why in just a second. Now after our mutation function, what we will add, right, we add on success property, and we pass here callback function. Now, as I told you, here we have two options. We can invalid our current card data, or we can update our cache data. The previous section, we update our case seller data because our new seller data is not adding in Jasen placeholder back end. But here, our cat data will get s in our back end. So instead of updating case data, we can simply invalid our current data. Here by invalidating the current card data, we are ensuring that our user gets his fresh card data. So here, we have to use query client and how can we get that right? By calling use Query client at the top and simply store it in variable called query client. Now, in our own success, we add query client dot Invalid Queries. And inside this, we have to object, which query key property and which key we want to invalid right. We invalidate cart save the changes, and back to our app component. Now here at the top, after use data, we call our use at to cart function. And we know this will return mutation variable. So we store that in variable called head to cart mutation. Now at the bottom, we just need to call mutate function using head to cart mutation variable. Now let's comment out this code, and we simply call here head to cart mutation dot mutate function. Now what we want to pass at the first parameter. We can check that here in our mutation function. See, we need to pass object with ID and quantity. So back to our component, here we add object and ID to product dot underscore ID and quantity to quantity. Now you might ask why we pass here object? Can we separately pass ID and quantity? No, that will not work because as we see in previous section in muted function, we have to pass all our parameters at the first position at the second position, we can add configuration object with on success and on error properties. Here, we already added on success in our use mutation function. We don't need it here. Here, we only need on error arrow function. What we will do in on error. We will revert our card if something goes wrong in head to cart API. See, here we have already one dispatch method for reverting card array. So we simply copy that and paste it here, and that's it. Previously, we use context variable because we are returning data on mutation function. But here we don't have mutate, so we can directly do that. Save the changes and take cog. Now on products page, we click on Add to Cart button, and our application crashed. Let me see in the console. See, here we cannot use product variable before initializing. Here we have error in our card reducer file. Open card reducer file and in our head to cart case, here we are using product to underscore ID before we initialize product variable. Let's move this before this line, save the changes and take a look. Here, we get another error for head to cart API which we removed. We have to also remove this input from our app component. Save this and now it will work. Let's click on head to Cart button. Nothing happens. Let me check in the query dev tools. We go to the mutations and here we can see we have error. Let's check this error. As we know in this on error property, here we get our error and simply console dot log this error. Save this and open up Console. Click on at to Cart button, and here we get our error and see it is telling API client is not defined. Oh, we forgot to input API client in our use head to card file, and that's how we solve problems. Save the changes and take a look. Let me close all these and click on head to Cart button. See here it is working, but it is taking time to update because we didn't apply optimistic approach. Now if we understand optimistic approach is basically we'll display changes on our website before calling our EPI. If API request completes successfully, then we leave our data as it is or refatch it from server for confirmation. And if API request gets error, then we revert our data. Simple as that. Now here, we just need to update our local card data before calling API. We can do that using two methods. First one, we have to use mutate function, but inside it, we have to write the same logic which we write in our head to cart reducer. So instead of using mutate, we can simply dispatch here action with head to cart action type. See here we already have this dispatch function, copy this and paste it before we call mutate function, simple as that. Now we can also remove this comment out code, save the changes, and take a look. See, now we have optimistic approach. 212. Mutation for Remove from Cart: Now, let's add mutation for our remove from card feature. You can also take this as exercise and try to implement remove from card feature. And then what's the solution? So here we create a new file called use remove from cart dot js. Inside this, we create function, use remove from cart equals to arrow function, and at the end, we export default, use, remove from cart. Now here we return use mutation function, and inside it, we pass configuration object. And first property is mutation function. And here we have to add remove from card API. So we go to the Card Services file and we can cut this API and also remove this function. Save this. And in our mutation function, here, we return this API, and we add then method, response, and return response dot data, and make sure we import API client from our Utils because I forgot to import it many times when I copy API from another files. After that, we add success property. Here we add callback function and inside this, we have to invalid our card query. We need here query client and for that, we need query client. At the top, we call use query client function and we store that in variable called query client. Now let's at query client dot Invalidate queries. Inside this, we add Object with query key to cart. Save this file and in our app component, after our use at TCAT Hook, we call use remove from card Hook and we store it in variable called remove from card mutation. At the bottom, in our remove from cart function, after this dispatch function, we add remove from cart mutation dot mutate function. And inside this first, we will pass parameter object, which is our ID. Hey, did we add ID parameter in our mutation function? Let me verify this. See, here I forgot to add destructure object and get ID as parameter. Save this and back to our file. Now after our parameter object, we add one more object in which we can add properties. So we add on error and pass error function, and inside it, we want to simply revert our card state. So we can copy this dispatch function from here and also we can copy this toast dot error function. I think that will help. So we pase them in our on error function. Now we can remove this old API call. We don't need it. And also, I like to add this error ts notification in the head to cart API. Save the changes and take a look repress the page. Here we get error. Let's console this. Here we are getting our card services does not provide an export named remove from card API. Or, we forgot to remove Import of our remove from card API. Remove this. Save this file, and our remove from card feature is working well. Now let's move to our last mutation, which is Update card. 213. Mutation for Increase and decrease: Now let's implement our last mutation, which is for increase and decrease. So first of all, we will create separate hooks for both API, and then we will call it in our app component. So in our card hooks folder, we create a new file called use increased product dot JS, and as you know, we first create a new function called use increase product with arrow function syntax, and at the end, we simply export default, this use increased product function. Now inside this function, we return use mutation hook and we add our configuration object inside it. Here, we add mutation function to arrow function, and we need here increased product API. So we go to the card services file and cut this increase API and paste it in our mutation function. At last, we have to add dot VN method and we have response and return response dot data. Simple as that. Now here we need this product ID. So here we will get object with ID parameter and make sure we will pass it in our mutate function in app component. And also, we import here API client. Now, let's add another property called on success, and we pass callback function here. Inside this callback function, we need query client. So before our written statement, we add Cs query client equals to here we call use query client function. You can see how easily we are making mutations in our application. It will only convince you when you implement it first time. After that, you will easily add it. I know you already complete this hook logic while I'm talking. So let me also complete this code. Here, we simply add query client dot invalid queries, and inside it, we pass configuration object with property query key and pass here card, which is the data we want to invalid. Now here, I notice one thing in decrease product API, we just need to change this API and point so we can make common API for increase and decrease. I think it will more beneficial. First of all, we will change our file name to us updcard dot js. Good. Also, we change the function name, select this and press F two on keyboard and right here, use Update card. Now here in our mutation function parameter, after our product ID, we add also type of update. And at the place of this increase, we add dollar CLibackets, type, save the changes, and in our app component at the top, first we remove these both API from card services, we don't want that now in our component, after our use removed from card, we call our use update card hook and we store it in new variable called Update card mutation. Now scroll down to the date card function. Here in the I condition, we have to increase the product. So here we call update card mutation dot mutate. And at the first parameter, what we will add write, object with parameter. You are doing really great. So here we add object with ID and type properties. Remember, here we are using objects because we have multiple parameters for mutation function. Now, after our parameter object, we pass another object for on error property. And we pass here callback function and inside, simply move these two lines. Now let's remove this old API call. Also, here we can see for these both functions, these two statements are going to be the same. Just we need condition for this quantity update. So we can move this dispatch card and update card mutation line after these both if conditions and also remove the dispatch card and API call from the second I condition. Save the changes, and also we can remove card services file from our project. We don't need it anymore. Now let's check our implementation. See, our increase and decrease function is also working well. So that's how we implement mutation in our cartridge project, and it will definitely improve the performance of our website. As I show you at the beginning, here are before and after comparison. We can clearly see that after reacquiry performance of our project is much better. So thank you so much for watching this complete section. 214. Section 19 Deployment: Now it is time. We have completed our major project, which is Card Wish Ecommerce application. Currently, our project is running on the local host, so let's deploy it on the Internet. And after that, you can directly share that website link with your friends, and also you can add that in your CV or portfolio. It is really simple. So let's start deployment process. 215. Beginning of Deployment: Now let's start our application deployment process. So here in our project, we have two parts, backend and front end. Without backend, our front end application is nothing. So we have to deploy these two parts. We will use render for our backend, and for front end, we will use Netlify. These are my personal choice for deployment. If you are going to work in some company, then selecting the service is your manager or client choice because they have to also see budget and facilities. First, we will upload our code on Github and then connect our Github repository with our services. Don't worry about that. It is really simple. We'll explain all steps in simple and easy way. If you want to deploy react application without backend, then you can skip next three lessons and directly prepare react application for deployment. But before that, you have to upload your project on Github. Now the reason we also deploy backend in this project is we don't need to start our local server when we access our react application. In our first two projects, we can only deploy our front end because in that projects, we don't have any backend or database. 216. Adding MongoDB Cloud: So currently in our backend, we have local MongoDB database. Now, as we deploy our application, both frontend and backend, our application can access by any user, but not all users have Mongo Dibe in their system. And also, that is not a good thing. Our application data should stay sync for all users. So we have to create our Mongo Db database in Cloud. By that, all users will use the same database. So head over to mongodb.com and simply sign up with your account. It will take only 1 minute to register. I already sign up, so I get this interface. Now from here, click on New Project and give your project name, which is CAT Wish, and click on next. Now from here, you can add team members to your project. Just simply click on Create Project. Now, click on Build database. Here, you can see like plan. We simply go to free version and click on Create. Now here we get our username and password for our database. So first of all, I copy user name and in note paid, we paste it. After that, also copy this random password and paste it also. This is the most important step. Now click on create user. Next, we have to give access to Network, which can read and write data in our database. So we select here, give Network access to everyone. Don't worry about that. Simply click on finish and close. Go to database. Now we just need to give network access to everyone. From anywhere, user can access our database and get products from it. In the left side, go to the Network Access. Here we have our current address. Click on Edit and simply Clic on allow access from anywhere. This will set our address to 0000, which is access for everyone and click on Confirm. This will take some time and see it is active. Good. So our database is ready. Now we just need to connect this database to our node back end. So back to the database tab and simplicly Cconnect. Now se like connect application option. And here we have steps for connecting node application. Don't worry, just simply copy this database link, and in our backend Vs code, open dot NV file, and at the place of this local Mongo Db ink, we paste our Mongo Di B Cloud ink. Now open up not paired and copy our password. Back to Va code, and we have to paste our password at the place of this password. Note that here we have to remove these angle brackets also. Save this file and we are done here. Let's verify it is connected or not. In our terminal, stop this running server by Control plus C or Command plus C and again write node index dot Js and hit Enter. This will take some time and see here we get database connected. Now again, stop this script and run node products dot js, because currently we don't have any data in this new cloud database, and C we get successful message. So back to our MongoV website and click on Browse collections. And see, here we get our database and collections. So we successfully connect Mongo Debi Cloud database with our node application. 217. How to upload projects on github: Now, let's see how we can upload our project to the Github. If you don't know Github, in short, it's a website that allows developers to store, share and collaborate on code with others. Github allows developers to create repositories, or we can call repos where they can store their code and track changes over time. And this is the best and easy way for teams to work together on a same project without overwriting each other's code. So there are many ways to upload code on Github. We will see the easiest and the simplest way, which is by using Github desktop application. So step number one, download Github desktop application. So head over to our browser and search Github desktop application and open this Github link. Now, click on the Download button. This will take some time. And after completing this, open the setup and our installation is started. If you open it first time, then you have to login with your Github account. So to show you this, I remove my Github account from Github application. Now, step number two, we have to login with Github account. So for Login, go to files and open Options and click on the sign in for Github button and continue with Browser. So it will redirect us to Github official website. Now fill your user name and password for your Github account and click on sign in. Now click on this Open Github desktop, and it will automatically redirect to our application. Don't worry. You need to only set up for the first time. Now let's verify we log in or not. So again, go to the files and open options. And in the accounts we can see here, we have our Github account. Now go to the Git option, and from here, we can set our name and email for our Github. So when we push cool to the Github, other team members will see this name and email. Make sure you select your official email here and click on Save. Now step number three, adding local repository. So for adding our code to repository, go to the file and select Add local repository. And from here, select the path of our back end folder. And select that folder. Now here it says to create new repository, so click on that link, and here we have to pass our repository name. Don't worry about that, just click on Create repository and click on Create repository. Now, let's verify we had right path or not. Circlkon showing Explorer and C, our Ben folder is open. So close it and simply click on this public repository. From here, we can change our repository name and also description, this is not backend for cartwage application. And also from here, we can select the privacy of our code. For our use, please don't make it private. Uncheck this box and click on Publish repository. It will take some time and done. Let's see it in Github. Click on View on Github and see here we can see our backend code. Low you can see how simple it is to upload code on Github. Now let's also publish our front end. So back to Github application, go to the file and click on at Local Repository. Select the path of our front end project. And click on Create Repository. Again, click on Create Repository and simply click on Published Repository. Here, we can change our apoame to CartwisFront end. You can write whatever you want to. It's totally up to you. In the description we add, this is React application for CartwishPject. Let's check this checkbox for making our repository public. We can in this from Github website. Click on publish and it's done. Let's open it in Github and see how front end is also published on Github. 218. Deploying Backend: Now, let's deploy our backend first. So head over to render.com, and here we can see instant deployment process. But first of all, we will register our account from here. We can use Google or Github for registration, or we can simply use email and password. It will send us activation email, and in that email, we get activation link. So I copy this link from here and paste it in our URL. And we get this test board. Don't worry about that. Simply click on New button. And here we select web services. Now we need to connect our Gitub account. Cl C Connect Gitub and login with your Gitub account. Make sure you use the same Github account in which you publish your backend code. Now let's install render in our Github account. From this page, we can select which repository we want to add in our Render account. You can add all repository, but in my suggestion, select only select a repository option. Now from here, we can select repository. So we select Cardwig backend and click on Install. Now this will redirect us to the Dashboard home, and we again click on New and select web services. See, now we get here our repository. Simply click on Connect, and we get here our form. Now, first of all, here we add our application name, which is Cartwig backend. Next, we can select region and branch of our Github repository. Now for root directory, we add dot. Next, we have environment which is set to node. Don't change that. And for build command, we write NPM install. And for start command, we simply add node index dot js. Now from bottom, we select our service type which we set to free. Now click on this Advanced dropdown and select Add secret File and give it a name dot ENV. Now back to our Bend project, and in that, we have ENV file in which we have our secret variables. Simply copy all code in Render website, click on contents and paste our code here. Now just click on Create web surveys and see how deployment process is started. It will take some time and see be successful, and now it is deploying. And see server is running on this port and I get error in Mongo Deb connection. Let me check this. I think I made mistake in adding Secret file. So here we go to Environment tab, and here, let me check the file contents. It is good. Oh, here I enter wrong file name. We have to add dot ENV. Save the changes, and back to Logs tab. Here, click on Manual Deploy Option and select Deploy Latest command. It will again deploy our application. Here we get build successful and deploying and see, here we get database connected. Let's verify this. So at the top, here we get our back end URL, copy that, and in the new tab, we page this URL slash API slash Products and see, here we get our products data. So we successfully deploy our back end. Now next, we prepare our front end for deployment. 219. Preparing our React application for deployment: Now, let's prepare our react application for deployment. So in our current application, we are calling our API with SDTP local host 5,000, but this is the local back end. We need to call API with our deployed application URL, which we see in our last lesson. So in our Carts React application, we open our API client file, and here we define our base URL for API calls. Also, we have to update our base URL for our images. We will define our base URL at single place, and by using it, we replace our old URL in all places. So in our source folder, we create a new file called config dot JCN and here we add Cul brackets and add here property backend URL. And in value, we copy our backend URL, and paste it here. Save this file, and now we replace all URL with it. So first of all, open api client dot Js file, and at the top, we import Config from. Here we go one folder up config dot JcN. Now let's remove this base URL, and here we add back ticks and add here dollar Cal brackets, config, BN URL, and after that, slash API. Save this and open product card component at the top, we import config from. Here we go to folders up, Config touch and file. Now in our JSX, let's replace this URL with dollar Cul brackets, config dot backend URL. Save this file and open single product component. Here at the top, we again import config from. Here we go to folders up, config dot JS and file. Now she like backend URL and press Control plus D or Command plus D and replace it with dollar Cul brackets and config dot Bend URL. Save this file and open product side bar. At the top, again, we import Config from to folders up, config dot js and file. Now, let's replace this URL with dollar Culiackets config dot enURL. Save this and last open card page component and at the top, we import config from two folders up, config, touches and file. Now let's replace this URL with dollar Coli Brackets, config dot Bn URL, and save this file. Now let's push our updated code to the Github repository. So one Github desktop application and select our front end repository as current. And here we can see all changes which we make in our code. Right here, message, update Ben URL and click on Commit to Maine then simply push origin, and we are done here. 220. Deploying React Application: Now let's deploy our react application to the Netlify. So head over tontlfy.com, and click on signup for Register yourself. Here I register with my Github account and this will ask for authentication. So Clic on authorize Netlify, and we redirect to the Netlify page. Here we have to answer some common questions about Netlify. Here I select work. After that, I select something else, and here we enter our application name, Cartwis. Now quickly answer these questions. It doesn't matter. We can change that later. Just at the end, click on continue to deploy. Now here we are going to use Deploy with Github, and that will again ask for authorization. Allow it, same as we authorize our Github to render. And after that, we simply get the installation process for Netlifi. So here we select only selected repository, and at the bottom, we select our CartwgFront end application and click on Install. Now from here, we can see our repository is added in Netlifi click on that and it will simply ask to deploy our project to Netlify. So click on that and our code is started initializing. You can see here starting to install dependencies. This will take little time, and after that, it is building and deploying and all process is done. Here we get Deploy success message, and our application name is set to this for just now. Don't worry about that. Just click on Get started. Here we can see we get our website, and this is the link of our website. Click on that and see we get our react application. Here, our application URL is random URL. We can't share this link to our client, right. So back to our Netlify website, and here we have our site settings, and also we have domain settings, so click on domain settings, and from here, click on Options and edit the site name. Now, we set our site ename to something unique, which is not already a label. So for you, you have to add cartdge one or two or something else to make it unique. Save this name, and now our website URL is changed. We successfully deploy our application on Netlify for completely free. If you want to remove this netlify dot app, then you have to connect your own domain with this site. If you are going to only use this application to show your work as developer, then this name is okay. Now let me show you how you can simply update your project. So here in our website, we want to change this website, title, and Fab icon. So back to VSCode, and in our index dot STMLFle at the place of this title, we add CATWish modern ecommerce application. Now in our SS folder, we have Cartwishpvicon dot Swig file. So simply move it in public folder. And at the place of this SVG file, we simply add Cart Wig favicon dot SVG. Save the changes. And now let's deploy these changes. So to update the deployed application, we just need to push our code to Github and Netlify will automatically detect the changes, and that's why we are react project to the Github. So back to Github dextra application. And here we pass our commit message, which is update title, and fab icon, and Commit to main. And at the end, simply push origin. Now, in our Netliive website, go to the deployment section, and here we can see it is building, and at the end, site is published. Let's open the site and see our icon is updated. So that's how we deploy our react applications. You can see deployment process is really simple and easy. Just you need to upload your code in Github repository, and then by using Netlify, we'll deploy our application quickly. And to update our application, we just need to push the changes to the Github, and in the two to 3 minutes, our site will rebuild simple as that. 221. Thank you!: All right, this is the end of this course. It was good one, right? It was long one, but you can see projects which you have created and also congratulation to make it to the end. I know from the stats that not many people make it here, but you have made it. We are here at the end of this course. Thank you so much and yeah, see you. Bye.