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.