Welcome to the ultimate react course. In this course, you will learn everything you need to know about React from the basics to more advanced concepts. So by the end of the course, you'll be able to confidently build fast and scalable apps with React.
If you're looking for a comprehensive, easy to follow, well organized and practical course that takes you from zero to hero, this is the right React course for you. You won't need any prior knowledge of React to get started. Everything you need to know is right here.
So you won't need to jump back and forth between random tutorials. Now, unlike other courses, we won't be building a dummy app. Instead, we'll be building and deploying a beautiful production grade app for discovering video games.
This app has all the features and UI patterns you would expect. from a modern application. We can toggle between the dark and light modes, we can search for games, filter them by genre, as well as platform. Now as we change filters, the page title gets updated dynamically. We can also sort games, and here we see loading skeletons while games are being fetched from the backend.
And that's just the start. In the next part, which I'm currently working on, we'll dive into advanced topics like routing, state management, fetching data with react query, authentication, error handling, performance optimization, and much, much more. I put my heart and soul into creating this course and I'm confident that it's going to be a game changer for your react skills. I'm Mosh Hamadani, I'm a software engineer with over 20 years of experience, and I've taught millions of people how to code and become professional software engineers through my YouTube channel and online school codewithmosh.com.
If you're new here, make sure to subscribe as I upload new videos all the time So if you're ready to master react and build front-end apps with confidence, let's jump in and get started Before we get started, let's talk about what you will need to know to take this course first things first You don't need to know react to take this course. However, you should have a good understanding of HTML CSS and JavaScript If you're comfortable writing code in these languages, you are in a great position to start learning react now throughout the course We'll be using typescript. TypeScript is a super set of JavaScript that adds static typing to the language Essentially it helps us catch errors earlier in the development process which can save us time and headaches down the road now Don't worry if you have never coded in typescript before I'll hold your hands and teach you everything from scratch.
With that out of the way, we can dive right into learning React. Before we begin coding, let's take a few minutes and discuss what React is and how it helps us create better applications. React is a JavaScript library for building dynamic and interactive user interfaces. It was created at Facebook in 2011 and is currently the most widely used JavaScript library for front end development. So if you're looking for a job as a front end developer, you should know how to confidently build applications with React.
But why was React created? Well, as you probably know, when a webpage is loaded in a browser, the browser takes the HTML code and creates a tree-like structure called the document object model or the DOM for short. This allows us to use JavaScript and change the page content in response to user actions.
For example, we can use javascript to hide an element when a button is clicked. This is called vanilla javascript, meaning plain javascript code without any third party tools. Now, as our applications grow, working with the DOM can become quite complex and challenging to manage.
This is where React comes into play. With React, we no longer need to worry about querying and updating DOM elements. Instead, we describe a webpage using small reusable components react will take care of efficiently creating and updating DOM elements.
So components help us write reusable, modular, and better organized code. Now let's look at a real world example. Imagine you want to build a webpage like this. On this page we have a navigation bar on the top, a side panel on the left, and a grid of video games in the main area.
We can build each of these sections as separate components. Now in this grid, each game is displayed in a cart, which is an independent component with a like button. That's another component itself.
We can build all these components individually, and then combine them to build this page. Essentially a react application is a tree of components with the app being the root, bringing everything together. Alright, that's enough theory for now, next we're gonna set up our development environment and get a feel for what it's like to build applications with react. Alright, to take this course, you need to have Node version 16 or higher. Now to check the version of Node on your machine, open up your command prompt or terminal window, and run Node-V.
So on this machine I'm running Node version 19, you might be running a newer version, that's totally fine, it's not going to impact the materials in this course, but you need to have Node version 16 or higher. If you don't, head over to nodejs.org and download the latest version on this page. Now in this course, just like my other courses, I'll be using Visual Studio Code or VS Code as my editor. You're welcome to use any editor that you prefer, but if you want to use VS Code, I strongly suggest you to use the pre-dir extension for formatting your code.
So here's the extensions panel, over here, search for pre-dir and install this extension. once you do that, on the top, under the code menu, go to preferences and settings. Now this layout might be different on Windows or Linux, I'm not entirely sure, but find the settings dialog, and on this page, search for format on save. If you tick this box, every time you save a file, that file gets automatically reformatted.
With all that, now we are ready to create our first React application. There are two ways to create a react app. We can use the official tool provided by the react team.
It's called create react app or CRA. But we also have another tool called Vite that's getting increasingly popular these days because it's much faster and gives us smaller bundle sizes. So here in the terminal window, I'm currently on my desktop.
To create a new app using Vite, all you have to do is run npm create Vite. at latest, or if you want to use the exact same version as me, which is what I recommend you, because I want to make sure you have the exact same experience, then you need to specify the version that is Okay? Now npm is asking if you want to install this package, let's proceed. Next we need to specify our project name, which is vit-project by default, but we can change that to anything like react-app.
next we need to select a framework, so using Vite we can create any kind of javascript project, we can use vanilla javascript, which is javascript without any third party tools, we can also create a view project, a react project and so on. So using up and down arrows we can move down this list. Let's select react, next we need to select a language, so here we have javascript and typescript, we're going to use typescript in this course. Good, so now we have a new project, next we need to go into this folder, install all the third party dependencies and run our web server. So let's cd into the react app folder and type npm install or npm i that is shorter and with this we can install all the third party libraries.
Alright, now we need to open this project in VS code. To do that we type code period. If this doesn't work on your machine Simply drag and drop that folder into vs code now here in vs code We can open an embedded terminal by pressing control and back tick if this doesn't work on your machine Just go to the terminal window and open a new terminal.
You can also see the shortcut right here So this is our embedded terminal It's much easier to use this than switch back and forth between vs code and a different terminal window now to run our web server We type NPM run now this launched a web server at this address, localhost port 5173, this might be different on your machine so don't worry about that just open this address in your browser, and this is our first react application. Next, we are going to create our first react component. So this is our project loaded in vs code, now, let me give you a brief overview of the key files and folders in this project. Here we have the node modules folder, this is where all the third party libraries like react and other tools are installed. You never have to touch this.
Next, we have the public folder, this is where the public assets of our website exist, like images, video files, and so on. Next we have the source folder, this is the source code of our application. In this folder, currently we have a component called the app component.
Now don't worry about any of the code here, we're going to rewrite everything from scratch. All I want you to note here is that currently in this application, we have a single component called the app component. Now, outside of the source folder, we have index.html, which is a very basic HTML template. In this template, we have a div with the id of root that is the container for our application.
Below that we have a script element, referencing source slash main dot tsx, this is the entry point to our application. Next, we have package dot json, in this file you can find information about this project, so we have the name of the project, its version, a bunch of scripts, the list of dependencies, so currently we are dependent on two libraries, react and react dom version 18. We also have a bunch of development dependencies, these are only used for development, they're not going to be deployed with our application in the future. Next we have a TypeScript configuration file, here we have a bunch of settings for telling the TypeScript compiler how to compile our code to JavaScript. Now for the most part, you never have to touch this file unless you're an advanced user. And finally we also have a configuration file for Vite.
Again, for the most part, you don't have to touch this file. Now, to create a react component, we right click on the source folder and add a new file called message.tsx. So the extension of typescript files should be either ts or tsx. Quite often we use ts for plain typescript files and tsx for react components.
Now, there are two ways to create a react component. We can use a javascript class or a function. These days function based components have become more popular because they are more concise.
and easier to write. So that's what we'll use in this course. But if you're maintaining an older React project that is built with class components, you can look at my previous React course to learn about them. But function based components are the recommended approach for new projects. So here we declare a function called message.
Now pay attention to how I have named this function. This convention is called Pascal casing. With Pascal casing we should capitalize the first letter of every word, in this case p and c.
It's really important to follow this convention because this is the convention that both React and other developers expect us to follow. So in React application, whenever we want to create a function component, we should always follow Pascal casing. Now, here we should describe what the UI is going to look like wherever we use this component. So let's say wherever we use this component, we want to render an h1 element with a message like hello world. So here the return.
and h1 element with hello world. Now this syntax might make you a little bit confused, you might be thinking that you're writing html code in the middle of javascript code, but that is not correct. This syntax you see here is called jsx, which is short for javascript xml.
So this code, under the hood, is going to get compiled down to javascript. If you head over to babeljs.io slash repl, that is r-e-p-l you can see how this code gets converted to javascript, let me show you. So on the left side, we can write JSX code, like h1 hello world, and on the right side we can see the equivalent javascript code.
So this piece of code gets eventually converted to react.createElement, the type of element is h1, and the message inside the element is hello world. So this is a very basic component, now to use this, first we need to export it as a default object from this module, now let's go to the app component, and use this new component. So back to our project, here's the app component, now we're going to delete everything in this file. Now let's create a new component called app, now in this component, let's say we want to have a div, and inside the div we want to have our message component.
So first we need to import our message component from slash message, so period means the current folder, now we can use this component just like regular HTML elements. So we add the opening tag, and close it. It's really important to close it, we should always close our react components, or we'll get a compilation error.
Now here we can also use the self-closing syntax, that is more concise. Now, just like the message component, we should export the app component, so it can be used Somewhere else. Now here in the terminal you can see our web server is still running, and here we have hmr, which is short for hot module replacement, so Vite under the hood monitors our files for changes, whenever we make any changes, it will automatically refresh our page in the browser.
So now you can see our message component rendered on the screen. Now this is a very simple example, in a real world application, a component can have behavior. So here we can have a button, when the button gets clicked, perhaps we can change the message, we can do all sorts of things.
So with JSX we can easily describe the user interface of our application with HTML and JavaScript. Now the great thing about JSX is that it allows us to easily create dynamic content. For example, here we can declare a constant called name, I set it to my name mosh, now we can replace this word with my name dynamically.
So here we add braces, and inside the braces we can write any javascript expression, an expression is a piece of code that produces a value, so here we can reference the name constant, we can also call a function like get name, basically any piece of code that returns a value. So here we can add my name dynamically, we can also write if statements, so we can say if name is true theme, return this markup, otherwise return a different markup, like hello world. Now back to the browser, you can see my name is rendered on the screen, however, if I change the name to an empty string, we see hello world. So this is the beauty of JSX. Using this syntax, we can easily describe the user interface of our applications.
So currently we have a component tree, with the app being the root or top level component, and the message being a child. When our application starts, react takes this component tree and builds a JavaScript data structure called the virtual DOM. This virtual DOM is different from the actual DOM in the browser.
It's a lightweight in memory representation of our component tree, where each node represents a component and its properties. When the state or the data of a component changes, react updates the corresponding node in the virtual DOM to reflect the new state. Then it compares the current version of virtual DOM with the previous version to identify the nodes that should be updated.
It will then update those nodes in the actual DOM. Now, technically, updating the DOM is not done by React itself, it's done by a companion library called React DOM. So earlier we talked about package.json, in this file we can see the dependencies of our application. So currently our application is dependent on two libraries. react and react dom.
Let me show you how these work together. So, in index.html, I told you that we have a div with the id of root, and this is the container of our application. Below that we have a script element referencing main.tsx.
Now if you look at this file, you can see that here we are using react dom to render this component tree inside an element with the id of root. So this is our component tree, here is our app component that is wrapped by another component called strict mode. This is one of the built in components in react, it doesn't have a visual representation, it's purpose is to identify potential problems. So we are taking this component tree and rendering or displaying it inside an element with the idea of root.
And to do that, we are using the react dom library. But we can also render this component tree in a mobile app using a different library called react native. So react itself is not tied to a particular platform like web or mobile, it's platform agnostic, and we can use it to build apps for web, mobile, and desktop devices.
So you have learned that react is a javascript library for creating user interfaces. In contrast to react, we have other tools like and view which are frameworks. But what is the difference between a library and a framework? A library is a tool that provides specific functionality while a framework provides a set of tools and guidelines for building applications.
So a library is like a tool while a framework is like a toolset. Now, React is just a library or a tool for building user interfaces. So the only thing that it does and is good at is creating dynamic and interactive user interfaces.
but we hardly use only react to build modern applications, we often need additional tools for concerns such as routing, which means allowing the user to go from one page to another. making HTTP calls, managing the application state, internationalization, form validation, animations and so on. Now the great thing about React is that it doesn't have an opinion about the additional tools we should use for these concerns.
So we can pick the right tools for the job. In this part of the course, our focus is entirely on React and new third party libraries. Once you master React in the next part, we'll explore some additional useful libraries in the React ecosystem. Hey guys, Mosh here.
Before we dive back into the tutorial, I just wanted to say that this tutorial is actually the first hour of my complete react course. The full course includes 8 hours of content, jam-packed with the latest techniques and best practices. It's got everything you need to become a react pro, including exercises, summary notes, cheat sheets, and even the project I showed you at the beginning of this tutorial. The best part is it comes with a 30-day money-back guarantee. So, if you're loving this tutorial and want to take your React skills to the next level, I highly recommend checking out the complete course using the link below this video.
Thanks for watching, and now let's get back to the tutorial. So, you got a taste of building applications with React. In this section, we'll be covering the fundamental concepts in React applications.
This is the most important section in this course you don't want to miss. The materials I've covered here help you build a strong foundation in react. We'll talk about building components rendering markup with JSX managing state passing input to components for props and debugging react applications.
So let's jump in and get started Alright, in this lesson we're going to create a basic script component. First we're going to install bootstrap to give our application a modern look and feel. Now in case you're not familiar with bootstrap, it's a very popular CSS library that gives us a bunch of CSS classes for styling our applications.
So here we open up our terminal window, you can see our web server is running, so we open a new terminal window, and run npm install bootstrap, the version that I'm using in this video is 5.2. 2.3. Let's go ahead, good, now we need to import it in one of our CSS files. So here in the source folder we have a couple of CSS files, one is app.css this file contains all the styles for our app component, we don't need any of this stuff anymore, delete, we also have index.css where we have global styles for our application.
Again, we don't need any of these styles here because all of them were generated by Vite. So we can delete this file entirely, now let's go to main.tsx, you can see that our index.css file was imported here, we're going to replace this line with import bootstrap slash dist slash css slash bootstrap.css okay, now to make sure that bootstrap is imported properly we go back to the browser So previously hello world was in the middle of the page and we had a different font, now it's up here and it has a different font. Beautiful.
So now let's create a list group component. So back to our project, here in the source folder we add a new folder called components. This is not necessary, but by convention we put all of our components in a folder called components. Now here we add a new file called list group.tsx. Again, pay attention to how I have named this file, here we're following the Pascal convention, so we're capitalizing the first letter of each word.
Now, in this file we declare a function called list group, for now let's just return an h1 element, list group and export this from this module. Next, we need to import this in our app component. So if you're on mac, press command and p and you'll see that it's now in the list group. if you're on windows, press ctrl and p, here we can search for files like app.tsx, okay?
Now, we don't need the message component anymore, so let's remove this line, instead we're going to import our list group component, okay? And we're going to use that right here, okay? Let's make sure everything is working up to this point. So, here in the browser, we have our list group component, beautiful, now finally we need to display a list of items here. And for that we're going to borrow some code from bootstrap.
So head over to getbootstrap.com, go to the docs, and on the left side, under components section, you should find list group, so this is a list group component in bootstrap, to create a list like this, we need to use this markup, so we need a ul with this class, and a bunch of list items with these classes, so we copy this we go back to our list group component, and return this markup Now here we get a bunch of errors, because class is a reserved keyword in javascript or typescript. So here we need to rename all these classes to class name. Now let me show you another shortcut.
Let's revert this back, we select the class keyword, now if you're on mac, press command and d, if you're on windows, press control and d, and with this we select the next occurrence of the selected keyword. So now we have multiple cursors. We can press command and d one more time, and again, and again, and again, now all of these are selected, so we delete them and type class name, then we press escape a couple of times to disable multi-cursor editing, ok?
Now finally, I save the changes, but my code is not reformatted so let's investigate why this is happening, on the top under the view menu, we go to the command palette, note the shortcut on mac is shift command and p, and here we search for format document. Okay, here we have an error saying there are multiple formatters for typescript JSX files, so let's click on configure, and here we're going to use predier as our default code formatter. Good, now this file is formatted, beautiful. Just note that predier automatically wrapped our JSX markup in parenthesis, this is necessary to break the markup into multiple lines. So if you're not using VS code with predier, be sure to add the left bracket in front of the return keyword, so you can spread your jsx into multiple lines.
So now back to the browser, here's our list group component. But this is pretty boring, this doesn't have any functionality, and it doesn't allow us to render or display these items dynamically. So we're going to solve these issues one by one over the next few lessons.
what if we want to add a heading here? Well, if we add another element here, like an h1, we get a bunch of errors, because in React, a component cannot return more than one element. So earlier I told you that, this h1 expression that we have here, eventually gets compiled to JavaScript.
So this line gets translated to something like React. createElement, with h1 being the type of the element. The same thing will happen for the second element. So in this function, we are returning multiple elements, and this is not allowed in React. Now, to solve this problem, we have a couple of different ways.
One simple way is to wrap this entire expression inside a div or another element. So let me show you another shortcut. We select all this code, then we bring up the command palette.
So we go to the view menu, and bring up the command palette, or better, we use the shortcut. And here we search for wrap with abbreviation, now we press enter, and here we specify the type of element that we want to use to wrap this entire code, so div, enter, done, okay, so that's one way but we are adding one extra element in the DOM purely for making React happy, this is unnecessary, a better way is to use a fragment so on the top we import fragment from React make sure to put it in braces now we replace the div with a fragment, so just like before I've selected the div element, now we can press command and d to select the other div, and now with multiple cursors we can edit both of them in one go, ok? Now with this change, when this component is rendered on the screen, we're not going to have an additional element like a div in the DOM, ok? Now there is even a better way to achieve the same result, we have a shorter syntax.
we don't have to import the fragment component from react, so let's delete this line, and we select the fragment tags, both of them, and remove them. So if you add empty angle brackets, we're telling react to use a fragment to wrap all these children. Now back to the browser, so here's our heading and our items, beautiful.
Now, this list is kind of useless because we have hard coded these items in our markup. what if we want to render a list of items dynamically? Well, let's declare a constant called items, and set it to an array of strings.
Here we can use the name of cities like New York, San Francisco, Tokyo, London, and Paris. Now, in JSX, we don't have a for loop, so we cannot write code like for item in items rendered, whatever. It doesn't work that way. So we have to use a different technique. In javascript, as you probably know, arrays have a method called map for mapping or converting each item to an item of a different type.
So if we type items dot map, here we can pass an arrow function, we can say take each item and convert it to an item of a different type. So here we want to convert each item to an li element. So here we type li and inside the tags, we want to render or display the item itself.
Earlier I told you that in JSX, we use curly braces to render data dynamically. So here we render the item itself. Now, we're going to delete all these list items, and instead we're going to bring down this piece of code.
However, we get a compilation error, because this expression is not allowed in the middle of a JSX markup. In JSX, we can only use html elements or other react components. So to render data dynamically, we need to wrap this expression in braces.
Okay? Now save the changes, our code got reformatted, so pre-plugin broke down our code into multiple lines and added parenthesis to wrap them. Now back to the browser, here's our list of zillies, beautiful While reviewing this video, I just realized that I made a mistake earlier and forgot to apply a CSS class to our list items.
That's why we have lost styling here. But don't worry, I'll fix that in a later video. However, if we right click anywhere on this page and go to inspect, this is Chrome developer tools, you should probably be familiar with it.
Here on the console tab, we have a warning saying, each child in a list should have a unique key prop. What does this mean? Well, Back to our code, this is where we are mapping each item to a list item.
Here, the warning is saying that each list item should have a key prop or a key property that uniquely identifies that item. React needs this to keep track of our items. So later, when we add or remove items dynamically, React knows what part of the page should be updated.
So when rendering a list of items using the map method, we should give each item a unique key. Now in this case, each item is a unique string, so we can use the item itself as a unique key, but in a real world application where we retrieve items from an API, quite often each item has a property like id. We don't have that in this case, so we don't have to worry about it. Now, back to the browser, let's refresh, the warning is gone, and here's our list, beautiful.
Sometimes, we want to render different content based on certain conditions. For example, here we can add an if statement, and say if items the length equals 0, perhaps we want to show the user a different message. So here we can return a completely different markup.
For example, we can add a paragraph, and here we say no item found. Now to make sure this works, I'm going to change the constant to a variable, so we can reassign this on the next line, ok, now back in the browser, so here we have no item found, beautiful, but our heading is gone, so we can come back here and add our heading as well, list, and now we need to wrap this entire expression inside a fragment, so let's add a fragment, ok, now if I save the changes, 3d reformats our code, and here once again we have parenthesis for spreading this code over multiple lights. With this, our heading is back, but I don't like this implementation because we have a bit of duplication, and generally speaking, duplication in code is not considered a good practice.
So let me show you a different way to achieve the same result. We're going to get rid of the if statement, instead we're going to render things conditionally inside our JSX expression. However, inside this JSX expression, we cannot write an if statement, because as i told you earlier, here we can only use html elements, or other react components. the only exception is braces, with braces we can render anything dynamically, so here we can use the ternary operator in javascript, so we start with our condition, items.length equals 0, then we type a question mark, if this condition is true, we're going to return a paragraph with this message, otherwise we're going to return null, meaning nothing will be rendered, with this, we have the same result as before, and our implementation is a little bit more concise.
Now, sometimes this logic can get a little bit too complicated and it can pollute our JSX markup. In those cases, we can always extract this logic and store it in a separate variable or constant. For example, here we can declare a constant called message, now we move this expression right here, and then we can simply render our message constant in our jsx markup. So now our jsx markup is a little bit cleaner.
Now we can also move this logic inside a function. For example, we can declare a function called getMessage, and here I'm using the arrow function syntax. Now we can move this logic right here, and now we don't need this constant anymore. So here we have a function, and we can call that function to get the right message.
Now the benefit of using a function in this case is that our functions can have parameters. So perhaps we can get different messages depending on different conditions. So here we can pass different arguments like 1 or whatever and get a different message.
If you don't have that scenario, it's better to use a constant in this case. Now, let me revert this code back to the previous state. I'm going to move this expression right here so I can show you more concise way to write the same code. So let's remove this function.
Okay, look, this piece of code is fine and it works, but the part that bugs me a little bit is the second part, returning null here. Let me show you a better way to write this code. We start with our condition, items.length equals 0. Now instead of using the ternary operator, instead of using a question mark, we do a logical and between condition and the value that we want to return if this condition is true.
That is the paragraph element. Okay? With this implementation, we don't have the null keyword and our code is a little bit more concise. But how does this work? Well, let's go back to the browser and open up chrome developer tools, here in the console tab, this is going to be our javascript playground.
If you have a boolean value like true, and perform a logical and with another value like 1, see what happened? The result of this entire expression is equal to the second value. What if we type true and mosh? The result of the expression is mosh. Now what if we have false and mosh?
The result is false. So what does this mean? Well, that means if our condition is true, the result of this entire expression will be our paragraph element.
but if the condition is false, the result of the entire expression will be false and nothing will be rendered on the screen. So this is a very common technique react developers use to render content dynamically. With this we can remove this line and this is our final implementation.
Alright, now let's see how we can handle click events in a component. First I'm going to remove this line. so we bring back our items, good, now I just realized that earlier I made a mistake and forgot to apply one of the bootstrap classes to these items, so back to our code, this is where we're rendering a list item, we should give this a class of list dash group dash item, okay, that's better, now we want to be able to click on each item and see it on the console, in react each element has a property where prop called on click. So here we said on click to braces. Now inside the braces we can write an arrow function.
So a function with no parameters. And here we can just say console.log clicked. As simple as that. Now I'm going to save the changes. So the code is reformatted.
So now each property or each prop is on a separate line. Okay. Now back to the browser.
We had an internal server error from this web server. Don't worry about it. Just refresh. The error is gone. Now, if we click on each item, we see this message, beautiful.
But what if you want to see the actual item that was clicked? Well, look, this is where we are mapping each item to a list item. So when creating this list item, we have access to each item.
Because we are using that item as the key of each list item, right? So instead of logging clicked, we can simply log item. Now, if we click on each item, we see it on the console, beautiful.
and by the way, when mapping items, we can optionally add a second parameter as an index, and with this we can see the index of the item that was clicked. So, let me show you, I'm going to clear the console, now if we click on each item, we can also see its index in the array. Lovely. Now, this arrow function can optionally have a parameter that represents the browser event. We can call that e or e.
whatever we prefer. Now let's log this on the console and see what we get. So clear, click, look, the type of this object is synthetic base event.
I know, it's a fancy term, this is one of the built in classes in react, because different browsers have different implementations of event objects, so to make this cross browser, react team have created a class called synthetic base event, that is a wrapper around the native browser event object. Now if you look at the properties of this object, you see properties that you're probably familiar with, for example we have client x and client y, which represent the position where we clicked, we also have type, which represents the type of event, we have target, which is the element where I clicked, that was a list item with this class. Now our event handling logic here is very simple, it's just a one liner, So writing a function here is totally fine, but if our logic gets more complex, we don't want to write that logic here in the middle of a JSX markup, instead, we should move that logic into a separate function.
So, in this component, we declare a function, by convention, we start with the word handle, and then we specify the type of event, in this case, click. Now we set this to, let's grab this piece of code, and paste it here, now we have a warning from the typescript compiler saying parameter event implicitly has an any type. So the reason I know this is a typescript issue is that here we have ts that is short for typescript. But why are we getting this warning?
Well, the reason we're getting this error is that the typescript compiler doesn't know the type of this parameter. Is event a number? Is it a string?
Is it an object? What is it? So if we use the dot operator, we cannot see.
any properties of this event object. This is where we need to specify the type of our parameter, so we get auto completion and type safety. So let's hover our mouse over this event parameter, look, the type of this parameter is react.mouseEvent.
So when we pass an inline function here, the TypeScript compiler knows the type of our parameter, that is why we didn't get a warning earlier. But in this case, we're declaring a brand new function, the TypeScript compiler doesn't know where we are going to use this, so it doesn't know the type of this parameter. So we should go on the top and import mouse event from react, and then after the parameter, we type a colon followed by its type. This is called type annotation in typescript.
So with type annotation, we can specify the type of our variables, parameters and so on. Now with this annotation, if we use the dot operator, we can see all the properties, of this mouse event object. This is one of the beauties of typescript.
We get auto completion, we get type safety, and it's easier to refactor or restructure our code. You'll see more examples as we go through the course. So, let's finish this example.
So now we have a function here, this function is called an event handler. Because it's job is handling an event, in this case, the click event. Now, over here, we're going to remove this inline function, and simply reference our handle click function. Note that I'm not calling this function, we don't want to call it, we just want to pass a reference.
So we're telling react that whenever the user clicks on this event, this function should be called. So calling this function will be done later at run time. Now, let's make sure everything is working, so let's click on one of these items, beautiful. Alright, now the next step, when we click on an item, we want to highlight it. To do that we have a css class in bootstrap called active.
So back to our code, this is where we are rendering a list item, I'm going to give this a second class called active, now look all of them are highlighted or activated, this is not what we want, we want to highlight one item at a time. To do that we need a variable to keep track of the index of the selected item. So back to our component, let's declare a variable called selected index, we can initialize this to a negative 1, that means no item is selected, if we set this to 0, that means the first item should be selected, now, down here, we can render this active class dynamically, so we're going to use the same technique you learned in the conditional rendering lesson, so I'm going to remove the quotations, here we add braces, so we render content dynamically, here we can check, the selected index.
If it equals the index of the current item, that means that item should be active. So we're going to give it two classes, list group item and active. Otherwise, we should only give it the list group item class. This is a very simple way to add classes dynamically.
There are other more advanced techniques, let's not worry about them at this stage, let's just see if this works or not. So, back to the browser. Now the first item is selected, beautiful.
Now when we click on an item, we should change the selected index. So this is where we're handling the click event. Now in this case, we need a simple arrow function to update the selected index.
So I'm going to get rid of this handle click function. So we delete it from here, as well as here. We should also delete the mouse event import on the top.
So always... pay attention to cleaning up your code. So here we write a simple error function, and here we set selected index to the index of the current item.
Okay? Now back to the browser, let's click on an item, nothing is happening. Why is that?
Well, this variable we have declared here is local to this function component. So React is not aware of it. It's like a little secret inside this component.
To solve this problem, we should tell React that this component is going to have data or state that might change over time and to do that we have to use one of the built-in functions in react called use state so when we type this here and press enter it gets imported on the top okay now this function is called a hook a hook is a function that allows us to tap into built-in features in react so this is called the state hook we have other hooks that you will learn about as we go through this course using the state hook we can tell react that this component can have data or state that will change over time. So instead of declaring a variable this way, we're going to call this function, now we're going to initialize our variable, we can give it the initial value of negative 1, now this returns an array, in this array we're going to have two elements, the first element is going to be a variable, like our selected index variable, and the second element is going to be an updater function. Using that updater function, we can update this variable, and at that point, React will be notified, so it knows that the state of our component is changed, and then it will re-render our component, which causes the DOM to be updated under the hood. So, as I told you earlier in the course, with React, we almost never have to touch the DOM directly. We think in terms of components that have state.
when the state of a component changes, react will update the DOM to match the new component state. Now let's see how we can use this. So instead of working with two individual elements here, it's easier to destructure this array into two elements. So the first element is going to be selected index, and the second element is going to be a function which we call set selected index. This is a convention we follow in react applications.
So here we have a state variable called selected index, and here we have a function called set selected index. Now as another example, we can use the state hook to declare another variable called name. So we call use state, we can initialize the name to an empty string, this returns an array which we can destructure into two elements, name and set name.
That's the idea. Now, in this case we don't need a name variable, so let's delete this line. and the comment and the slide.
So here we have a state variable called selected index, now down here to update this variable we're going to call set selected index, and give it the new index. With this, when we click on an item, it gets selected. Beautiful.
So this is how we tell react that our component can have state that will change over time. Now one thing you need to know about component state is that each component is going to have its own state. So if we go back to our app component and add another instance of our list group here, each list group is going to have its own state. So, in our first list group, tires is selected, but in our second list group, nothing is selected because this component has its own state. So they will be independent of each other.
Now, we don't need two list groups here, so I'm going to remove the second one. So we're showing a list of cities here, but What if we want to show a list of names or a list of colors? We don't want to recreate a separate component for each type of list, right?
So how can we make this component reusable? This is where we use props or properties Props are the inputs to our components. So back to our code instead of defining these items here We should be able to pass them as an input to this component Just like how we can call a function and give it an argument now the same principle applies to this heading. Instead of hard coding this label here, it would be nicer if we could pass different labels, like cities, names, colors and so on.
So how can we do that? Well, first we need to decide the shape of the input to this component. So we should be able to pass an object with two properties.
Items, which is going to be an array, and heading, which is going to be a string. To do that, we use one of the typescript features called an interface. using an interface we can define the shape or the interface of an object, so we start with the interface keyword, give this a name, by convention we use props, but some people prefer to prefix it with the name of the component, so list group props. Either way works, I prefer a shorter name, now here in braces we define various properties and their types, so we want to have items which is going to be an array of strings, so string array, and heading which is going to be a string.
So once again, we are using type annotation to specify the type of various properties, okay? Now, we don't need this comment anymore, next we give this function a parameter called props of type props. Now, if we go back to our app component, we have two compilation errors saying type is missing the following properties from type props.
items and heading. So the typescript compiler is saying that this component expects two properties which are items and heading, we have not specified them. This is yet another benefit of using typescript. So the typescript compiler is reminding us that we have forgotten to pass these props.
So it's helping us to catch a bunch of potential errors at compile time before running our application. So back to our list group, I'm going to grab the list of items and move it to the app component, now we can pass this just like how we said the attribute of html element. So we said items to, we add braces so we can reference this variable. Now similarly we should also set the heading to cities.
Now in this case I'm using quotation marks but we could also wrap this in braces, but this is unnecessary because we're passing a static value. So let's rewrite it, that's better. now the compilation error is gone, so back to our list group component, now, there are a couple of issues here, we don't have the items variable anymore, so we have to prefix it with props dot, okay?
But we have to do the same thing here, which looks a little bit repetitive and ugly. A better solution is to destructure this parameter right here, so we remove the name and add braces, and pick the two properties, items and heading. now we have access to these properties anywhere in this function. So we can remove props.
and our code is cleaner. Now the final part is to replace the list with the heading dynamically. Okay, back to the browser, our app is still working.
So using props we can pass data to our components. Alright, our list group component is in a fairly good shape. When we click an item, it gets selected.
But in a real world application, quite often, something should happen after an item is selected. Perhaps we want to filter a list of objects, or maybe we want to redirect the user to a different page, so something should happen after an item is selected. Now what happens is different from one application to another.
There is no one size fits all. So we don't want to implement that piece of logic inside our list group component because then it's not going to be a reusable component anymore. So we need a mechanism to notify the consumer or the parent of this component that an item is selected. In this case, the consumer or the parent of this component is our app component.
This is where we are using the list group. So when an item is selected, we should notify the app component that an item is selected. But how can we implement this?
Well, that's very easy. So look at our props object. Currently we have two properties and we are using these to pass data to our list group component.
Now we can add a third property which is going to be a function. Now down here, when we select an item, we're going to call that function. With this, our app component will be notified. Let me show you how this works. It's really simple.
So first let's define the signature of that function. Let's imagine that we want a function that takes a parameter called item of type string, that is the selected item, and returns void. So it doesn't return a value. so here we have a property, by convention we start with the word on, and then we specify the type of event, in this case, select item, this is just like the on click prop that you saw earlier, but here we have on select item, so we have a property called on select item, the type of this property is a function that has a parameter of type string and returns void, ok, with that now we have a compilation error in our app component, how can I tell? Look, it turned red.
Also, we can go to the top, under view, open up the problems panel, so the TypeScript compiler is telling us that in the app component, we have forgotten to pass this prop. So once again, the TypeScript compiler is helping us catch a lot of potential problems early on. So, let's go back to our app component, now here we set on select item, we can write an inline function here, just like how we handled the click event earlier, or we can write a separate event handler. If you want to write a separate event handler, again, just like before, by convention, we start with the word handle, and then we specify the type of event, select item.
Now we set this to a function with the signature that we just defined, so item of type string goes to nothing. Now here we can just do a console.log, and print the item on the console. Now, we can pass that down here, handle select item.
Now the last step, back to our list group, over here, when destructuring the props, we should pick the unselect item property, and then when selecting the item, we should call this function. So we call this and pass the selected item, which is this item variable here. back to the browser, when we select an item, the app component is notified and it's now printing the name of the selected city on the console.
Now let's talk about the differences and similarities between props and state. As you have seen, props or properties are the inputs or arguments passed to a component. State on the other hand is the internal data managed by a component that can change over time.
So props are like function arguments and state is like local variables inside a function. Now one thing you need to know about props is that we should treat them as immutable. What does this mean?
In English, to mutate something means to change it. So mutable means changeable and immutable means unchangeable. So when we say something is immutable, it means it's read only.
So in our list group component, here are our props, we should not change any of them here. we should not set the heading to a new value. If we do so, nothing is going to happen, nobody is going to yell at us, but this is an anti-pattern in React.
You will understand the philosophy behind this as we go through the course. This is based on functional programming principles. So we should treat props as immutable or unchangeable.
State on the other hand is mutable, and that's the whole purpose of using state variables. We want to tell React that this component has data that can change over time, right? So these were the differences between state and props.
but one thing they both have in common is that anytime they change, react will re-render our component and update the DOM accordingly. Sometimes we want to pass children to a component, just like how we are passing a list group to this div element here. So in this lesson, I'm going to show you how to create a component that can accept children.
So, back to our components folder. let's add a new file called alert.tsx. Now let me show you a shortcut. Instead of defining a function here, and then exporting it, we can use a shortcut.
So here in the extensions panel, if you search for ES7+, you will find this extension. It's called ES7+, React, Redux, and React Native. It's a very popular extension. Look at how many times it's been downloaded.
So once you install this, you can type rfce, now it's not coming up, I don't know why, so let's close this file, and open it one more time, now let's try again, good, so this is short for react arrow function component export, so if you press enter, we get this code snippet, lovely, now here we have multi-cursor editing, so we can change the name of the component, if we made a mistake, but in this case no, so let's go back to alert, and then we press escape, to exit multi cursor editing. Good. Now we don't need to import react on the top, so here's our alert component. Now let's add this to our app component and test our application up to this point.
So we go to the app component, now we're done with our list group for now, so let's delete all the code here. Now inside this div we want to add an alert. So let's add alert, good. Now back to the browser. So here's our alert component, lovely.
Now to display an alert, we're going to borrow some code from bootstrap. So head over to bootstrap website, go to the docs, and here on the left side, under components you should find alerts. So let's find out the markup we need to render an alert like this.
So that is very straightforward, we need a div with two classes. The base class is alert, that all of these have. The second class is a class that determines the color.
So if we use alert primary, we get this blue alert by default. So back to our alert component, let's give this div a couple of classes, alert and alert primary. Alright, this is what we get, lovely. Now we need to make this dynamic. So we want to pass the text as a prop.
To do that, first we need to use an interface to define the shape of props. So props, here we need a property called text of type string. Then we add a parameter here of type props.
In fact, it's better to destructure this and grab the text property and render it right here. Okay, now back to our app component. Here we should set the text to something like hello world. Before going further, let's test our implementation.
Okay, it's working, lovely. Now while this works, this way of passing text to this component is kind of ugly, what if the text is a bit too long? What if you want to pass html content? Passing html content as a prop like this is kind of ugly. Wouldn't that be nicer if you could pass text as a child to this component?
Let me show you how. So we want to be able to use this component like this. This is better.
So to do that, we go back to our component, Now there is a special prop that all components support, and it's called children. So if we simply rename text to children, now we can pass our text as a child to this component. But we have a couple of errors, because we need to rename these two references to text, so I'm going to rename them both in one go, good, the errors are gone, and our application is still working, lovely. Now, what if you want to pass HTML content here?
we get a compilation error, because we told the typescript compiler that the children prop is a string. But in this case, we are not passing a string, we are passing a more complex structure. To solve this problem, we need to change the type of children from string to react node. Now here in the auto-completion box, we have two react nodes. The first one is an abbreviation, so if you press enter here, we get this markup.
This is not what we want, we want the second item. This is the react node class defined in the react module. so let's import it on the top like this, and with that we can pass html content to our alert component. So to recap, using the children prop, we can pass children to a component. Alright, the last thing we're going to cover in this section is react dev tools, which is a very useful browser extension for inspecting and analyzing our react applications.
it's available for chrome, firefox, and microsoft edge. So simply google react developer tools or react dev tools and install it in your browser. Once you do that, then go back to this page here in the dev tools, you will see a couple of new tabs, one is components, the other is profiler.
Now look at the components tab, here we can see the hierarchy of our components. So on the top we have the app component and below that we have the alert component. so this is the component tree that react takes and renders in the actual DOM.
Now, down here you can see the props of this component, so here we have the children prop, which is set to an array of two objects, the first element is a string, the second element is a span object. Below that you can see how this component was rendered, so it was rendered by the app component. Now finally down here you can see where this component is implemented, in this case in app.tsx.
but that is not visible in my recording window. Now, in a large application with a lot of components, finding the right component might be a little bit tedious, so we can always search for them here. Also here we have a couple more useful features, for example, we can select a component and inspect the matching DOM element.
So if we click this, and then go to the elements tab, we can see the matching DOM element that represents this component. Now back to the components tab, there's also another useful feature here, so we can select a component and click on this icon to see its source code. So in this case, this is our alert component.
So it's pretty straightforward, it doesn't really need more explanation. As you're building applications, if you want to better understand your components and how they work, if you want to inspect their props and state, use React F tools. Alright, now it's your turn. I want you to create a bootstrap button component.
So, here on bootstrap website, if you look at the buttons page, you can see we have different types of buttons. Now for this exercise, I want you to only focus on this set of buttons, because here we have other flavors, don't worry about them, don't worry about the sizes or outline buttons, just simple bootstrap buttons. Now, the markup is really simple, each button has two classes, one is btn, which is a base class, and the other is a class that identifies the color. So by default, primary buttons are blue, secondary buttons are gray, and so on.
So I want you to encapsulate this markup inside a reusable React component. So spend a few minutes on this, then be sure to come back and see my solution as I'll be showing you a really cool TypeScript technique. Alright, here in the components folder, we add a new file called button.tsx. now we use our shortcut, rafc, good, next we rename div to button, and give it a couple of classes. I'm typing a little bit too fast because I'm assuming you have already done your exercise, so I'm not expecting you to code along with me.
So here we have two classes, for now let's just stick to primary buttons and then we make this dynamic. So this is the approach I want you to take while building applications, one step at a time. don't try to do too many things together, okay? So for now I just want to render a basic button, I don't even want to make the text dynamic, let's see if our application works up to this point. So we go to our app component, and in this div we add a button component.
Okay, now back to the browser, here's our button, beautiful, so the first step is done, now the next step is to make the text or label dynamic. So, back to our button component, here we need to use an interface to define the shape of props, now I want to use the children prop here, so we can pass the text just like html buttons, so I'm going to set the type of children to string, we could also use react node, but I prefer to use a string in this case, next we add the props parameter and destructure it, and finally we render children Right here. good, now we go back to our app component and give this button a label like my button, let's see if our application is working, good again, don't worry about these errors, everything is good so far, next we need to handle the click event, because in a real world application, when this button is clicked, we have to do something, what happens next should not be implemented in our button component, otherwise it's not going to be reusable ok, so back to the button component here in the props object, we need to add a new prop called onClick, and this is going to be a function with no parameters that returns void.
Next, we add it here, onClick, and finally, we set the onClick prop of the HTML button to the function that is passed from the outside. So onClick is going to be a function that is passed from the outside, so the parent of this component is going to pass that function, we get that function and simply pass it to this HTML button. ok, now in our app component we have an error because we haven't set the unclick prop, for now I just want to add a simple inline function and log clicked on the console, let's see if our application is working so click, click, click, beautiful, now the final step is implementing the color, so we want to be able to pass the color of this button from the outside like this, so we can set it to primary or secondary or whatever.
So let's add a new prop called color, color of type string. I prefer to sort these props in alphabetical order, it makes our code a little bit easier to read, that's nicer. Next we add the color prop here, and we use that to add the second CSS class dynamically. So we wrap the code in braces, we terminate our string here, and then append the color right after.
Okay? We have a compilation error because this quotation mark is unnecessary. Good? Now, in our app component we have set the color to secondary, let's see if it's working, good, if we change it to primary, it's still working, great.
Now, what if you want to give this a default value? So we don't have to specify the color every single time. To do that, we go to our button class, and give this color prop a default value of primary. With that, we get this blue button, beautiful.
However, we have a compilation error in the app component saying property color is missing in type. So even though we gave this prop a default value, the typescript compiler still expects us to set the color prop when using the button component. To solve this problem, we have to tell the typescript compiler that this property is optional.
So we add a question mark after and now the error is gone. Okay? Now what if we pass an invalid caller here?
Like let's say react, what happens? Well, there are no errors or warnings, but this is not how a button is supposed to look like. This is where we can use typescript to catch this kind of bugs early on before we deploy our application.
Let me show you how. So, back to our button component, instead of setting the type of color to string, we can set it to a string literal like primary, and with this we can only set this property to the value of primary. So if we set it to something else, we get a compilation error. Now, we don't want to be limited to primary, we want to support other colors. So here we can use the union operator and add a second string literal.
So we can add secondary, we can also add danger, success, and other bootstrap colors. With this implementation, we can only set this property to one of these values and nothing else. So if we set it to react for example, the TypeScript compiler is yelling at us, we can see this file turned red, and also if we go to the view menu and look at the problems panel, we can see that we have a problem in this file.
So now if we change this back to primary or secondary or one of the supported values, the arrow goes away. Alright, here's the next exercise. I want you to write the necessary code, so when we click this button, we see an alert, and here we have a close button, when we click it, the alert disappears.
This is a great exercise for you to practice pretty much everything you have learned in this section. Now let me give you a hint. On Bootstrap website, look at the alerts component, on the right side you will find a link called dismissing.
Now, down here, you can see that to make an alert dismissible, you need to add a class here called alert dismissible, we should also add a button, this is the close button with this class and other stuff. So we'll spend a few minutes on this, then come back and see my solution. Alright, this is so much fun. So here in the app component, right above our button, we're going to add an alert, and here let's say my alert. Now before going any further, I just want to test our implementation up to this point.
I don't want to show or hide anything, I just want to make sure if we can see an alert. Beautiful. Now, we don't want to show this at all times, we want to show this only when this button is clicked.
To do that, we need a state variable here in the app component that determines the visibility of the alert. So we want to render this part only if that variable is true. So here we need to use the state hook, to declare a state variable, we initialize it to false, so our alert is initially hidden.
Now this returns an array that we can destructure into two elements. We can call the first one alert visible, and the second one set alert visibility. You could call them anything, whatever you prefer. Now we want to render the alert only if alert is visible. Alert visible is true.
So we wrap this in braces, and perform a logical and between alert visible and this expression. So alert visible and. Okay? Now, when we click the button, instead of logging something on the console, we simply call set alert visibility to true. So set alert visibility to true.
Let's see if our implementation is working. Alright, now we click, and here's our alert. Beautiful. Let me explain how this works.
So when we click on this button, this function is called. At this point, we set our state variable to true. So the state of this component is changed, and React will re-render this component and all its children. This is why we see the alert. Now we need to add the close button to the alert.
So here on bootstrap website, I'm going to copy some code, I'm going to grab this class, so there are no typos. Let's add that to our alert. component. Okay?
We also need a close button. I'm going to copy that from this website as well. Paste it here.
We just need to rename class to class name. Good. Now once again, before we implement the hiding logic, first we want to test our application and make sure that we can see the close button.
So one more time, click, okay, here's the close button. Now the final part. when we click this button, we should notify the app component that the user clicked on this button. At that point, the app component will set the visibility of the alert to false, which will cause the app component and all its children to re-render.
So to notify the parent or the consumer of this component that the user has clicked on the close button, here we need to add a new prop, onLose. So remember the convention, we start with the word on, and then we specify onLose. the event, in this case close.
This is going to be a function with no parameters that returns void. Now we need to add that here, and finally when the user clicks on this button, so unclick, we simply call unclose. Now more accurately we are not calling this function, we are not calling it like this, we are just setting unclick to unclose. So unclose will be a function that is passed from the outside, from the parent, we pass that function to this prop, when the user clicks on the close button, react will call that function for us. Now, we have a compilation error in the app component because we haven't set the unclose prop.
Now here we pass an error function and set alert visibility to false. As simple as that. Now, the final test, click, click, lovely. Congratulations, you made it to the end of this tutorial. I hope you found it helpful and learned a lot about react But wait, there is more this tutorial was just a small part of my complete react course The full course includes eight hours of content and is jam-packed with the latest tools and best practices You'll get access to exercises summary notes cheat sheets and the project I showed you at the beginning of this tutorial and if you're not completely satisfied No problem.
The course comes with a 30-day money-back guarantee So there is no risk in giving it a try. So if you are serious about master react, I encourage you to check out the full course using the link below this video. Thanks for watching and happy coding.