React Crash Course for Beginners 2021 - Learn ReactJS from Scratch in this 100% Free Tutorial!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi my name is maximilian schwartzmuller and in this course i will teach you all about react the most popular javascript library you can learn these days now in this course we're going to build a complete example project and you're going to learn all about the important key features you need to know about react step by step and therefore let's dive right in and let's dive into the most important question first what exactly is react so let's dive right into this video and this topic by answering the most important question first what exactly is react js and why would we use it why do we need it what's the problem it helps us solve regarding the what we can of course visit react.js.org the official webpage of react js and there we learn that react is a javascript library and it's a javascript library for building user interfaces now that's quite straightforward it's a library for the javascript programming language that helps us build user interfaces but what exactly does this nice sentence mean react.js is a library and to be precise it's a client-side library it's about client-side javascript so the javascript code which runs in the browsers of your visitors and that is important because we use javascript in the browser to manipulate web pages after they were loaded and that allows us to build rich highly interactive modern user interfaces for our websites take something like netflix for example which is actually built with react there we can browse around we can hover over one of the movies or sirius and we get more details there we can add it to our list and we can go to that list page and everything here happens very smoothly and also quickly we never need to click anywhere and load a new html page that refresh icon in the top left corner never spins because we never request a new html page we never have to wait for a new html page to be generated by the server and that happens because javascript is doing some work here and it's updating what we see on the screen the dom whilst we are working on that page and that gives us that nice user experience that nice ui which we know from mobile apps for example when we work with a mobile app we're used to things being very reactive there we can work with the app and switch between different screens without having that latency which we know from some websites without requesting new html pages behind the scenes so mobile apps therefore feel very reactive things happen instantly we don't need to wait for new pages to load or for actions to start and traditionally in web apps that was different there we often had to click a button and then wait for a new page to be loaded and to show up and whilst that of course also does work it is not the same user experience our users know from their mobile apps and it's often not the user experience we want to deliver therefore now that's a problem we can solve with javascript javascript in the browser because that allows us to manipulate the dom and therefore what the user sees without requesting a new html page and waiting for it and therefore just javascript would be enough but let me give you an example of just javascript and why we might want to use something like react instead of just javascript this is a very simple demo here i have some content on the page and when i click delete i get this overlay where i can confirm or cancel now both buttons don't do anything but close that overlay as does clicking that backdrop but what you see on this page here or what happens when we click delete all of that is controlled with javascript i got a html file with some very basic html content some styling which we can ignore and then the magic happens in this app.js file in there i got some code that in the end adds a listener to this main button which we got on the screen so to this delete button here and when that button is clicked i fire this show modal handler function and in there we run a bunch of javascript code to create various elements divs paragraphs and then the cancel and confirm buttons to configure those elements and add text or css classes and to add event listeners to those elements as well to then fire that close modal handler function which in the end removes the overlay this modal as we call it and then still in the show modal handler function i got some code that combines all those created elements and brings them onto the screen this is the javascript code responsible for opening this overlay here now it works and it's not too bad but it's quite some code for this simple action and here we only got one to do in this demo application if we would add multiple to-do's if we would repeat this html code multiple times to render more to-do's on the page or to even render those to-do's dynamically after fetching them from a database for example this code would become far more difficult far more complex for example i couldn't just select a a button on the page with that query selector because we would have multiple delete buttons for multiple to-do's and we would have to make sure that for different to-do's different overlays are opened and when we confirm the deletion the correct to-do is deleted we're not even doing that here in this demo but that would be more complexity which we have to add and handle if we build a more realistic app here a more realistic website and therefore just the javascript works and can sometimes be a good choice but it can also reach its limits and one of the reasons is that with just the javascript you have to write every single step that should be taken we want to create an element we want to set its content we want to add classes we want to add a click listener then what should happen on that click listener every single step needs to be described this way of programming and bringing something onto the screen is called an imperative approach we simply describe action after action step after step and that can reach its limits and in addition even if we don't reach any limits we as a developer have to take care about all the nitty-gritty details we have to run the low-level code for creating a button for setting its text content and therefore in the end we reinvent the wheel over and over again doing repetitive tasks now here's the same example with react this works in exactly the same way but the code looks very different i got a react project here and as a side note you find both code repositories both code snapshots attached and here in react.js this might look a bit more complex we got more files involved here but that's something we're going to learn throughout the course why we have multiple files but in the end this is the main code that's responsible for bringing this to do onto the screen and what's very interesting here is that we have like a custom html component here a custom html element and indeed react is all about those components react is all about splitting your application into small building blocks small components where every building block every component has a clear task and therefore your code stays maintainable and manageable and react the library will do the heavy lifting of rendering something on the screen and of combining all your code so for example if we look into the code for this custom element which we built here which lives in this 2.js file then we here again see that i have some html code for rendering a to do but that we have some kind of placeholder in here and then some kind of other code which we don't fully understand yet but which we will understand and learn about throughout this course and in the end that's the code responsible for rendering such a to do and for rendering the modal this overlay here as well and for rendering it conditionally and what's interesting here is that even though we don't understand this code yet and even though it's certainly strange that we have html code in javascript files even though that's all weird we can definitely see that we don't have a bunch of step-by-step instructions here instead we kind of define what we want to have as an end result and then we have some some placeholders some flexible elements there and then we have very simple instructions here which in the end then will be processed by react to change what's visible on the screen and all these low level instructions for creating elements and setting text continents on those instructions are not written by us when using react instead they will be written or defined if you want to call it like this by the react library we as a react developer work on a higher level which makes working with react and which makes building complex user interfaces way easier and that is why we want to use react js it makes building modern rich complex user interfaces easier and it does so by giving us a higher level syntax where we write code in a declarative way in a declarative component focused way we define what we want to have on the screen what the end goal is we create these custom html elements and react we'll do the rest and one side effect for example is that if we wanted more than one to do we could just copy that custom element change maybe that text that configuration and boom we got a second to do here and we got a button on that's to do which works as well and that is why we use technologies or frameworks like react now because things get easier with react and because we can build those rich user interfaces with react and javascript when working with react we often build so-called single page applications because whilst we can use react to control parts of a html page let's say some interactive sidebar and therefore we add a widget you could say to a page where only a part of the page is controlled with react it is more common to control the entire page with react which means that we use react for everything we see on the screen and even for switching pages so when we click on a link and we load a new page as i did with netflix when i clicked on my list it looks to the user as if we switch the page but we actually don't request a new html file from some server instead we just used javascript through react.js to change what's visible on the screen and that often leads to a smoother ui and a better user experience as you see it at the example of netflix it's built with react and there we never request a second html page hence it's a single page application where after the initial request to decide react takes over and controls what we see on the screen now throughout this course we are going to learn react in depth and we're going to start with this basic dummy demo here to learn about some core concepts and then later throughout the course we're going to build this meet up project this mini project here where we see more react features in action and where we can practice all those basics and where we then at the end really understand how react works and which features it brings now this course is about react but it is worth noting that there are alternatives to react js now we're going to focus on react here and react is one of the most popular front-end frameworks or libraries however you want to call it you can learn it's a lean and focused component based ui library it really focuses on this component thing and it doesn't have a lot of other features built in if you need other features like routing which we are going to learn about in this video then you need to bring extra third-party packages that's not horrible but it is something to be aware of react itself is really just focused on bringing stuff onto the screen and updating that for you and allowing you to build these custom html elements these components that's the core focus of react now an alternative to react which has more built-in features would be angular and never very important and very popular front-end framework and i got a course on this as well angular is a complete component-based ui framework so it also focuses on components just like react but it ships more built-in features than react it also embraces typescript right from the start and it can be overkill for smaller projects therefore since it has way more features built in but for a large project on the other hand you don't need to rely on the community as much because there's more built into that framework so that's simply a little consideration you have to make the syntax also looks a bit differently because whilst it is component focused building these components works a bit differently with angular than it does with react again i got a course on that if you want to check out angular as well and we also have another very popular framework another popular alternative and that would be vue.js vue.js is kind of like the mixture of angular and react in between those two extremes if you want to call it like this it's also a complete component-based ui framework and it also includes a lot of features but a bit less features than angular but more than react it includes core features like routing for example and therefore with vue you also have to rely less on the community and still you don't have as much overload possibly as you might have with angular depending on what you build i also got a more detailed comparison video on these free technologies in case you're interested in that now all three are super popular react currently is probably the most popular but all three are great i got courses on all three and therefore checking those out might be a good idea as well but this course of course is about react and therefore let's not lose any time let's dive right in so let's get started with react and let's dive into that react code and learn how to work with react and how to write react code now in the project i showed you before you might have noticed that i had a couple of files here in this react project and these files are actually javascript files but in those files i then use html code and that is not something you can normally do normally you can't add html in javascript at least not like this you can add it as part of a string or of a template literal but not just like that that's not syntax that would work out of the box that's not syntax that would work out of the box and indeed it wouldn't work just like this that's why for working with react we set up a project that's a little bit more complex than a vanilla javascript project in the standard javascript project i just have a html css and javascript file and in the html file i simply import those external files and then they do their thing because that is all just standard modern javascript with react to write react code in a convenient way we can't just set up a project like this because we want to use this html in javascript syntax and the browser would not understand this syntax out of the box that's why a react project is a bit more complex and involves more files because it involves a so-called build step which means the code we write will not be the code that ends up in the browser we simply write code in a very convenient way for us as a developer and then behind the scenes that code will be transformed before it reaches the browser and in addition to that build step with a modern react project we typically also want a development server which hosts our running react application locally on our machine and which for example updates the page in the browser whenever we make changes to our code so that we don't have to reload that page manually all the time and because that's the kind of setup we need we don't just create a couple of html and javascript files instead we typically create a react project with an extra tool that gives us all that behind the scenes magic added to the project automatically and the most popular tool for that would be create react app you can simply google for create dash react dash app and you either find this entry on the official docs or this github repository in the end you can use either of the two there you learn a bit more about it and that you might not need it but in reality for most react projects you do and then you learn how you can set up a project with that tool and it's in the end just one easy command now for this command to be executable on your system though you need to install node.js first now nodejs is a javascript runtime that allows you to run javascript outside of the browser we don't write any node.js code with react react is not a node.js library or framework it is about browser site javascript instead but we do need node.js to install this create react app tool or to use this create react app tool and the project generated by that tool we'll also use node.js behind the scenes for this automatically reloading development server and for some code transformations which transform the code we write into code that runs in the browser that's why you should visit nodejs.org and there install the latest node.js version whatever that version is when you're visiting this simply install the latest version here by clicking on it that will then give you an installer for your operating system it's available for mac os linux and windows and it should automatically select your operating system here and then you simply walk through that installer and install node.js here i'm on mac os but the process will in the end be the same on windows you can just accept all the defaults don't need to change anything there and that will then install node.js on your system now once that is done you are ready to run this npx create react app my app command and for this simply open up your default terminal or command prompt on windows and in there use the cd command to navigate into a folder where you want to create your react project your development folder your desktop anything like that then once you're in that folder once you navigated there inside of that terminal or a command prompt run npx create dash react dash app and then simply something like my first app or in my case react dash course simply hit enter thereafter and this will now create a new folder named react course in that folder in which you ran that command and here i need to confirm that i want to temporarily install this create react app tool and then this folder will be created off that name you chose here and in that folder a brand new react project will be set up for you now react project sounds like a big thing it will still be a simple web page with javascript javascript managed through react in the end but because of these transformations i discussed because of that it will be a project where all these transformation steps are already pre-configured for you so that you can focus on the code and not on the setup of the project now this can take a short while and if you're facing any problems here make sure you got no firewall blocking outgoing traffic or anything like that no antivirus tool that could be interfering here and then at some point you should be done you should see output that looks something like this now with that we can cd into that newly created folder and then run npm start which is a command based on the node package manager which is a tool that was installed together with node.js which will in the end execute a script that was pre-configured in that created react project and when we run this script a development server will be started as it says here which will host this react project it should open a new tab in your browser automatically on localhost 3000 and display a starting project there a starting website if it didn't simply manually go to localhost 3000 or whichever address is shown to you here and then you should see something like this the exact starting project can change over time since the starting project template can be changed by the create react app team but ultimately you should see something like this and that's now a little dummy website which was pre-built for us and which already exists in that starting project now we are going to get rid of that starting project here and build our own website though our own react project now i did now open this react course folder which we created in the last step with my editor visual studio code now you can use any code editor you want if you have a favorite editor already you can stick to this but you should use some code editor to have a better time working with react and here i'm using visual studio code which is a great free ide for web development it's available for all major platforms mac os windows linux you can simply download it from code.visualstudio.com and then once you download it and installed it simply open your folder that we created in the last step this react course folder in my case with visual studio code simply with file open or open folder on windows now once you did that you should see something like this now you can tweak the settings of visual studio code if you want to if you have a different theme and you want my theme you can go to preferences color theme i'm using the dark plus theme and it is worth noting that with visual studio code under view you can tweak the appearance of the editor for example if you have a status bar at the bottom and things like that which i disabled here and you can go to view extensions to install extra third-party extensions into visual studio code which can add new functionality now i got a bunch of extensions installed which you don't need but there is one extension which i do recommend and that's the prettier extension you can simply search for prettier here and then install that extra extension this is an extension that helps with code formatting and which therefore helps with making your code more readable with a simple keystroke for this you then also want to make sure that under preferences keyboard shortcuts if you search for format document you have this shortcut bound because that format document shortcut can then use prettier to format your code and make it more readable for this to ensure that you use prettier you might want to go to your settings to your user or project specific settings and then there simply search for format and under default formatter you want to select prettier vs code which should be available since we installed prettier now that's the setup i'm using here in the end and with that i got an editor configured for my requirements which we can now use to dive into that react project that was created for us and which we can now use to write some react code so let's now as a first step clean up this project to get rid of some of the starting files and then start from scratch again to learn react in depth now this project which was created for us has a couple of starting files which we don't need here for example a file for automated tests that is something which i cover in my complete guide course but we don't need it here so i'll get rid of that file and also of the logo svg report web vitals setup tests and app css if you got more files you can get rid of those as well you should be left with an index.js a app.js and an index css file thereafter now in index.js i will get rid of that import of report web vitals and i'll explain these imports in greater detail in a second for the moment let's just focus on cleaning up and i'll get rid of that code down there and i'll get rid of that strict mode because for the moment for getting started it is simpler if we just get started like this in index.css i'll get rid of all that code as well we're going to add different css codes soon and in app.js there i'll get rid of these two imports at the top and then of all the content here in this return statement all this html code for the moment we can just add a simple div here where we say hello now we can save that and that's now the starting setup with which i want to get started you also find this starting project snapshot attached to this video so that you can also download it from there and get started with that if you do download my attached snapshot though there is one important step you must not miss and you have to go through you have to install third-party dependencies of the project because since it is a bit of a more complex project setup working with third-party packages like the react project works a little bit differently here we got this package.json file which lists all the dependencies of this project and there we for example see the react library and another package which is part of the react library which are listed as dependencies now these dependencies are managed and installed automatically for us and a big code bundle with our code and that third-party library code will be generated automatically behind the scenes by those build steps which exist in this project as well those are brought in by that react scripts package now i am aware that this sounds fairly overwhelming and complex right now especially if you never worked with anything like react before and you're used to standard setups where you have a html file and a bunch of javascript imports but we can't ignore all of that for the moment we just add dependencies here and we can then import them into our javascript files that's what you see here with those strange import statements and then this build step which is part of this project setup which is started when we run one of these scripts like npm start which we did before these scripts will then in the end combine and transform all the code and combine the third-party package code with our code and make sure that the result is an output which the browser understands now because we have that setup if you download my attachment you need to run one extra command before everything here will work for you and for this it's best if you open the terminal or command prompt which is integrated into visual studio code with terminal new terminal which is your standard operating system terminal or command prompt just already integrated into this ide and any commands we run here are then automatically executed in this project folder and here you need to run the npm install command which will simply download all those dependencies this project has and store them in this node modules folder which we have here that's a folder in which we will never work because that holds all these third-party dependencies and their dependencies which our project needs so that's a folder which is here but which was not part of the attach code because it's a fairly large folder and hence the attachment would be unnecessarily big and you can simply recreate it by running npm install in that folder that has this package.json file so that's why we need to do that then and thereafter you can run npm start again to bring up that development server and i will do that here again and for this i'll go to that upper terminal where i ran npm start before and i'll quit this process with ctrl c now now as long as you don't quit that process the development server is up and running and listening to code changes to then display them in the browser you can quit this server whenever you're done with development for the day and then you simply restart it with npm start again if you want to pick up development again but now i'm not restarting it in this standalone terminal but instead in this integrated terminal which is already navigated into my project folder and the advantage of starting it here is that i will always immediately see any errors that might occur if i have an error in my code for example and that's why i'll start it here zoom out a bit make this a bit smaller and keep that up and running as long as i'm developing so don't close the terminal don't run ctrl c here keep it up and running and if you do that and you go back to localhost 3000 and reload you should just see hello there because of our cleanup process now that was a lot of work just to get started but i am a big fan of having a clean start and explaining what's going on here instead of just throwing code at you and leaving it up to you to figure out what's happening that's the project setup we're dealing with that's my ide and that's the cleaned up project which you also find attached and therefore now let's start writing our own code and let's understand these different react features and this strange syntax here step by step now with the project cleaned up let's explore react and let's write our own react code currently we got two javascript files here index.js and app.js the index.js file will be the starting point of our react application the code written in here will be the first code that will be executed in the browser when we load our project in the browser so what we see here in the browser is the result of this code line here executing in the end now we don't fully understand this code line yet but what we do in this file is we're importing a couple of things that is how in modern javascript supported by that build setup we have here supported by that npm start script and what it does behind the scenes how we combine multiple files and how we import features like objects or functions from file a into file b and here we're for example importing the react dom object from the react dom library so that's not an object we created that is an object created by the react team exposed in that react dom library which is part of our project because it's part of our dependencies here now on that object we call a render method and to that render method we pass this strange html code now this html in javascript syntax here only works because of that build step as mentioned before and it's actually called jsx this kind of code is called jsx code this html in javascript code jsx is a special syntax which is not understood by the browser and which therefore is converted behind the scenes but which is more convenient for us as a developer to write because working with react will be about building custom html elements these components and combining them together and that is way easier if we can't just write html code kind of in our javascript files to describe the desired output so here we kind of create or we use our own html element the app element which is actually imported from that app file the file extension is missing here because for javascript files it can be omitted and the second argument to the render method in the end just tells react where this element should be rendered in the real dom now here we're selecting an element by id with an id root and we can find this on the single page that is part of this project we find it in the public folder there we got a couple of images but also one html file that is the single html file that makes up this react application because i mentioned before you typically build these single page applications with react where only one html file is fetched from a server and then react takes over and controls the dom and what's visible on the screen now in this index.html file in the body section we got a div with an id root and that id root should look familiar that is the div which we in the end select with this document get element by id code snippet here and therefore in the end what we tell react with that line is that we want to render our app html element our custom html element which is defined in this app.js file into this place into the place of this element with this root id so into the place of that div here in the end that's what we're telling react that's why if we visit our page and we inspect it so we don't view the page source but we inspect it with the dev tools here when we have a look at the rendered dom here we see body that there is this div with an id of a root and in there we see our div with hello which is the content we defined in app.js and that should make sense because it is the app thing which we import from the app.js file which we render here now let's take a closer look at this app thing then that is a function a function which we export to make it available outside of this file but in the end just a standard function a standard javascript function the only special thing about that function is that it returns such jsx code so this html in javascript code that's the only special thing other than that it's a regular javascript function and that is super important what we have here is a so called react component we can use it like a html element as we're doing it here in index.js but it's of course not an html element the browser would know but one defined by us the developers of this project now this component as it's called in reacts world this custom html element is in the end just a function a function which is defined and exported and specifically a function that returns jsx that's important a component so a function that should act as a component and be usable as a component by react must return something that can be rendered in the browser that could be plain text it could be a couple of other things but it can and most typically will be html code as well so this jsx code and what's interesting is that in the browser if we have a look at the dom again we don't see our app element anywhere here we don't see an html tag called app instead we just see the content of our component here this div with hello as a text because these custom elements these are not known by the browser we just write this code in our react application and then when it runs in the browser react will not render these custom elements which wouldn't tell the browser anything but instead it will render the content returned by these custom elements and that's how these react components work in a nutshell that is already one very important first piece of knowledge here that we have these react components which are functions returning jsx which we can use to well tell react and therefore in the end the browser what should appear on the screen but of course we typically don't do that with just one simple component that just returns a div of hello instead i mentioned before that i want to rebuild this basic first example with this delete button and then there after dive into a little bit of a more complex project in a second step and therefore let's now work towards that first example with that delete button and that modal overlay now for this first example for this delete button let's remove this hello text and instead inside of this div i'll add another div i'll add another div and before that diva h1 tag where i say my to-do's because that was also some text which we had there and then this other div next to the h1 tag inside of the outer div that div will contain that signal to do that single to do item which we have in this dummy project for that i'll use a h2 tag for the title and then below that i want to have that delete button here now i'm using regular html elements here because when working with jsx you can use your own elements your own components if you have some but you can also use all the built-in default browser tags like divs paragraphs h1 tags buttons inputs and so on so in the end here in the component we just write the html code that should eventually appear on the screen so the output that should be rendered by the browser so for this we have our to-do item here and some title above it and on that button i'll now say delete that was the text we had here now for styling purposes we're going to add some styling soon i'll add another div here and actually put that button inside of that div and now i pressed this format document shortcut to auto format this code and make it a bit more readable now that's a more complex html structure and if we now save this file and we reload or actually we don't even need to reload because of this auto reloading built into the dev server we should see that output here the title the delete button and my to-do's now the delete button is not doing anything at the moment and the title also is just static text but we again see that we can influence what shows up in the browser with the code we define in our app component here now some styling would be nice and for this i attached the index css file which you also find attached here which contains some basic styling for this first demo you can simply replace your index css file with the attached one and if you do that and reload it looks a bit nicer and we can also now add some css classes here to this code some css classes that will also influence the styling for example to this div which contains the title and the nested div i want to add a class of card now in regular html you would do that by adding the class attribute and setting this to card for example now this is not how you should do it with react this code here looks like html but it actually isn't behind the scenes it is transformed to standard javascript and in standard javascript for one class is a keyword but even more important than that if you look at vanilla javascript the property name of html element object for assigning or for setting the css classes on that object is actually class name not class that's just how vanilla javascript works and therefore here the attribute name actually also is class name now again this can be confusing because it looks like html and in standard html that would be class but since this isn't html since this in the end is javascript just looking differently we need to keep minor things like this in mind now the good news is however that this is one of the very rare cases where the attribute name differs from the property name and we have to use the property name here and hence we don't use what we would write in standard html in most cases you can write standard html code here and the class name is the most prominent uh special case in react where you assign a css class to an element with class name as a attribute in quotes added to an element but with that if we save this again now we have this card look of this to do now there are a couple of other classes that should be added for example on this div which holds the button you should add a class name of actions and on the button here we add a class name of btn for a button we do all of that that's the look we get and that looks a bit nicer so now we also added some styling to our first component simply by changing the code in the index css file and adding a couple of classes here and therefore our first component is taking shape however at the moment all that code is in one component and there are a couple of reasons why we might want to split that up and also make our component a bit more flexible this first code here for our to-do element exists in this app component there's nothing wrong with it but not only do we have some static text here we would of course want the actual to-do title here not only is that the case if we would want to add a second to do we would have to replicate this entire code block and if we then ever want to change anything about that let's say we want to add extra span to that button whatever then we have to do this in all those places where we use the same code that's not really what we want to do that's why react embraces this concept of components of building our own building blocks which we then compose together for this i'll remove this duplicate code and instead create a new file a new file in that src folder which i'll name to do js the name is up to you the extension should be dot js though and that will simply hold another component we're going to build our second component here now typically those component files except for that so called root component this app component are stored in a separate components folder which i also added in the source folder so i'll move to do js into that folder that's not a must do but it is a convention to keep your project organized now in this to do js file i want to create my second component that to do component and we did learn that a component in react is just a function so in the end here we define a function to do and then we export that we need to export it like this with this syntax to make this function available outside of this file and usable in other files now one important note about this function name though you can name your component functions however you want but there is one important restriction one important thing to keep in mind the name of the function should start with a capital character that matters because when we later use this function as a component in our html code so if we use it as a custom html element then it will have to start with a capital character there as well to differentiate it from the built-in html elements react1's custom components to start with a capital character so now we have our function here and then here in this function we must return something that can be rendered to turn this function into a component and that something is this div here this div with the class name card i'll cut it from app.js and then return it here into do js and press that auto format shortcut again so now that's our to-do function returning this jsx code back in app.js we can now use this to do component and we don't do that by executing to do like a function as we would normally do that but instead we use it as a custom html element just as we did it with app in the index js file so here where i cut the code from i'll add to do like this as a html element the only special thing here is that it's self-closing alternatively we write our opening and closing tag this would work as well but since there will be no content between the tags we can also write a self-closing tag but then it has to have this forward slash it would not be allowed like this now as noted before it is worth pointing out here that this component this custom element when we're using it here in this jsx code that there it has to start with a capital character so to do with a lowercase t at the beginning would not be valid because react internally differentiates between built in html elements like divs and h1 tags and custom elements by casing all these built-in elements start with a lowercase character custom elements built by you or others have to start with the uppercase character and that is just something to be aware of now to use to do an app.js though we need to import it from the to do js file and for this at the top of this file we import to do from dot slash components to construct a relative path to that components folder slash to do again the file extension of dot js can be omitted here that's now this to do imported and rendered here if we now save all files we see the same output as before which is good that means that everything still works but we're now getting to that output with help of our separate component now if we want to have multiple to do's we just got to replicate this to do component here in the app component and we now have a couple of to-do's and if we now ever want to change anything about that to do component about this html markup that makes up a to-do we just need to do it in the to do js file like adding this span which has no real purpose but acts as a demo and if we then save that file we see that extra span in all our to-do's because we define it once and then re-use it multiple times just as in vanilla javascript we would define a function once and then possibly call it multiple times from different places in our application it's the same concept here with react components though we don't need to span here so i will get rid of that now what we do need here though is some configurability at the moment all to do is just say title and that's not too useful this should be different to do titles for our different to-do's and of course i can change the title here to learn react but since i do this in this to-do js file this will now affect all to-do usages again so all to do is which we're outputting so that's not how we make this more configurable instead we want to let the place where we used it to do so the app component pass different data into these to do components just as we pass arguments into functions when we call them to then output different data in each to-do instance depending on which data we're passing in and that's what we're going to do now to make our component a bit more configurable and accept different data we in the end wanna utilize a concept which we know from the function world and from standard html elements in the place where we used to do so in this app component it would be nice if we could add an attribute like text or title totally up to you let's go with text and then set this to some value like learn react on the first to do then master react on the second to do and let's say explore the full react course in the third to do now it would be nice if we could do that but if i add this here in app.js and save it this has no effect on what we see on the screen the reason for this is that we're setting these custom attributes but in the to do js file we have no code that would pick up those values nonetheless this is how you do pass data into a component we just also need to write some code in the component to then accept and use those received values and we do that with a concept called props we accept the parameter in our function component and in every function component we can accept that parameter and that parameter is typically called props you can name it whatever you want since it's your code but it's called props because this react concept is called props this will be an object props will be a javascript object where all the attributes added on the element are in the end available as key value pairs in this props object so here these attribute names will be the keys and the values will be well the values so props inside of the to do component will be an object now that has a text property and then different values for this text property and if you named this attribute differently that's also okay you will then have a property of that name in your props object so therefore now here in this h2 tag we want to output this text we're getting on this props object now in standard javascript we access object properties with the dot notation so we could output props dot text here to access the text property in the props object and therefore the value stored in this property but if we do this here we just see props.text as output the reason for this is that everything here in this jsx block is treated as html elements or plain text the good news however is that we can also output dynamic expressions as part of the jsx code we can tell react that something should not be treated as plain text but instead as a javascript expression that should be evaluated and we do this with a special syntax inside of this jsx code which looks like this opening and closing curly braces single curly braces and between those braces you can have any javascript expression you want like for example two plus two now this will not be treated as plain text but instead it will be executed as javascript so if i save this we see 4 the result of this expression now you can have any single line expression in here but you can't have any block statements here so adding a if check here would not work but what does work is referring to props.text here so simply outputting the result of accessing this text property on the props object if we add this code and save this we see our different texts here for the different to-do's and now we build our own truly reusable react component here that to-do component it is truly reusable because now it does not just have some hard-coded structure and text inside of it but also some dynamic code using this core concept built into react the props concept for accepting data from outside so from the place where it is being rendered that is a key concept this props concept and that is how you build reusable custom elements reusable components and that's therefore a major first step here now let's make sure that we handle events that we handle a click on the delete button and that we then also change something on the screen when the button is clicked to be precise that we present this nice overlay when that delete button is clicked so let's now make sure we can listen to a click on this delete button in vanilla javascript so in just javascript without react we would find a way of selecting this button for example with document query selector button and then once we got hold of this dom object we could add a click listener with addeventlistener now this is again an imperative approach we describe what should happen with react we rather use a declarative approach describing the target result and hence this is not code we write and react instead with react if we want to listen to a click on this button we add an extra attribute on this button and for this it's important to understand that all these default html elements are in the end also just react components just react components that are built into react already so they look like regular html elements and you use them like regular html elements but under the hood these are components and that matters because that means that you can add certain attributes which you could not add like this at least with just html for example on a button or actually on any html element here in jsx you can add a on click attribute written like this lowercase o uppercase c and the casing does matter unlike in regular html here it does matter now when you add the on click prop as it's called as you learned to a button or to any other element you're telling react that you want to react to a click on that element now the value you assign for this attribute is then not some text not a string but instead a dynamic expression which should hold a function that should be executed when a click occurs so here we could define an anonymous inline function like this or also with the arrow function syntax which you can use in modern javascript or you point at another function and i'll do the latter i'll create a new function and important i'll create it as a nested function inside of the to do function and that might look weird but that's actually standard javascript in javascript also without react you can define functions inside of functions so here i'll add a function inside of the to do function inside of that to do function component and we could name this delete handler the function name is totally up to you i personally like this convention where functions which are executed upon events and with handler but other people don't use that but instead might use handle delete or just delete totally up to you i'll go with delete handler here and then point at this function as a value here for this on click prop simply by repeating the function name here and now here is an extremely important thing to keep in mind you don't execute the function here so no parentheses if you would execute it here this function would be executed as soon as javascript and react evaluates this code so when this line of code is evaluated the function would execute now that is too early though we want to execute the function when the button is clicked not when that code is evaluated by javascript because that happens right before that content is rendered in the browser hence we just point at this function by just using its name here and that just tells react in the end that it's this function that should be executed when this element is clicked and now in here we can do whatever we want for example we can console.log clicked here for the moment and if we do that and save this if i go to the javascript console in the dev tools if we click one of these delete buttons doesn't matter which one you click you see clicked now we could also output clicked and then as an extra log props dot text so that text value which we receive via props which i also output down there in the h2 tag i'm now referring to it again here because this is just standard javascript in the end even though this jsx code definitely doesn't look like it but up here we write standard javascript and hence of course here we can also use one of our arguments and if that argument turns out to be an object which props is we can also drill into that object here with that if i save this and click delete you see the proper text being output here as well and maybe it's not clear here but that's another strength of react without any extra work from our side these three different buttons are doing different things i mean they're always doing the same thing we just defined this logic once but the concrete values with which they work the concrete text which they output is not the same instead it's different for every button and that means that we can easily write logic that's specific to a specific to do whilst still being able to define this logic once instead of three times which is great and makes our code way more reusable but of course here the goal is not to lock something to the console instead we wanna show a little overlay when that button is clicked and for this of course we need to first of all create that overlay we need to create the html code that should be showing up and then as a second step we also need to find a way of showing it conditionally now let's start with creating the code for the overlay for this i'll add a new component we could add the code in the existing component but it is considered a good practice to put every building block into its own file every component into its file and to avoid very long jsx blocks by instead splitting it up into separate components now when you should make a split that's something which will come with experience and you'll see a couple of examples throughout this course here but in general you want to keep your component functions small and maintainable the jsx code that belongs to a component shouldn't become too complex and therefore i'll add a new file in the components folder and i'll name it modal js because that's the component that should be responsible for rendering a modal this overlay that's typically called a modal and in here we therefore create another function the modal function and we export this function like this and here we can also accept this props parameter as i mentioned every component function gets this parameter it's passed in automatically by react but of course if you don't use this parameter in a function if you don't use it in a given component you can also omit it and here for the moment i will omit it then we need to return something here something which can be rendered by the browser as we learned and for me that will be another diff and in that div we can then have a paragraph let's say with a text of are you sure or something like this and below that let's say two buttons one button where we say cancel and one button where we say confirm now in this demo the buttons won't really do anything except for closing the modal but of course in a bigger application you could then trigger different actions based on which button was clicked but again that's just the first demo we're going to see a slightly bigger app thereafter in this course so for the moment it's this div let me format this with a paragraph and two buttons now we want to add some styling so on that div i'll add a class name as you learned of modal and on the buttons i'll also add some class names on the cancel button it's button and then another class named button dash dash alt and these are simply classes defined in the index css file i provided to you earlier and then here on the second button it's just a button and that's now the markup for this overlay component now in addition to this overlay we also want to have a backdrop some gray background behind the modal which blocks interaction with the page whilst the modal is opened and for this i'll add another component the backdrop component in a backdrop js file and that will also be a straightforward component simply a backdrop function here like this and then we export this as a default and here i just want to return a div with a class name of backdrop this div has no content and therefore we can write it as a self-closing tag actually in standard html you would not write it like this their divs are not wide tags but in jsx you are allowed to do that if you have no actual content between the opening and closing tags and here i just rendered this div because of this styling which is added by this class and hence i need no content and hence we can write it like a self-closing tag okay so now we got the backdrop and the modal now we can use both and for the moment we will always show both so for the moment we can go to app.js for example and below all these to do's we can now also output the modal as a self-closing tag like this and the backdrop as a self-closing tag like this and we again need to import these two component functions in order to use them here so we import modal from dot slash components modal and we import backdrop from dot slash components backdrop like this if you now save all your files you should see something like this let me zoom out a bit something like this this is our modal and at the moment it's always visible and we can't close it because that's now one big missing piece we know how to build components how to build reusable components and how to build our interface but at this point our interface is 100 static it never changes what we output here that never changes no matter how we interact with it as a user the interface always stays the same and of course that's typically not what you want in a web interface things should be interactive and things should change that's one of the main reasons for using a library like react and therefore let's now explore how react makes sure that we can change what we see after the page was loaded in order to change what's visible on the screen we need to change the state of this app so to say now attached you find an extra article and video which i created where i explain what state is in the end you can't take it quite literally though the current state of this application is that we have three to-do's and this overlay is open now we would like to also be able to present another state where this overlay is closed and we want to switch between the states when we click on delete then it should open and when we click on cancel or confirm or the backdrop it should close so that should be our ways of switching between the states and react has a built-in concept that helps us with that and conveniently it's called state for this let's go to our to do js file to our to-do component here we got this delete handler this function which is triggered when the delete button is clicked when it is clicked we would like to switch to the state where the modal is open to make that happen we need to import some functionality from the react library so we import from react important here we have node.slash because react is a third-party library you import from those by just referencing the library name and then we import something like this with curly braces we import the use state function that is a function exposed by the react library which we can use in our component functions with use state we register different states which we want to support in our react application and react will react to changes in that state and allow us as a developer to render different output depending on which state is active now that all starts with calling use state directly in our component function like this so not inside of the lead handler instead directly in the component function use state is a so called react hook and those react hooks can only be called directly in react component functions and in custom hooks which is a topic we'll not discuss in this course but which is discussed in depth in my complete guide as well for the moment it's enough that we know that we can use react hooks in react component functions now calling use state creates a state react is aware of now we can give this state a starting value by passing it here as an argument to use state and that could be false if our state is that we want to control whether the modal is open or not and initially it should not be open so the initial state is false now use state always returns an array with exactly two elements that's how you state works it always returns an array with two elements and we can store this returned array in a constant or we use array destructuring which is a javascript feature to store these two elements since we know that it will be always two elements in different constants and we could give the first constant a name of show modal or modal is open or anything like this and the second element here the second constant a name of set modal is open now why did i choose these names because the first element which use state returns in its array is the current state snapshot so this value which is stored in this state you can think of react state as a variable which is managed for you by react you define the initial value here and you will then also be able to change that value now you get access to the currently stored value through this first element here the second element is a function that allows you to change that value because you don't change it by assigning a new value to modal is open instead you always call this second function to assign a new value why does this matter because whenever you call this state changing function react will in the end re-execute the component function to which this state belongs and re-evaluate it and also update what's rendered on the screen this allows you to pick up the latest state value and possibly render something different depending on the state now this might still be a bit abstract it will become crystal clear in a couple of seconds what we can do now with these two elements is that in delete handler we call set mode is open and set this to true to change that modal is open state from false which is our initial state to true and then we use modal is open to conditionally render the modal and backdrop down there in this jsx code so i go to app.js and i remove modal and backdrop from there and remove the imports since we're not using modal and backdrop in this file anymore and instead i'll go to to do js and import model there from dot slash modal and import backdrop here from dot slash backdrop constructing the relative paths to these files as seen from inside this to do js file and since modal and backdrop are neighbors to this file the paths look just like this and then we can use these components down here let's say here in that diff modal and backdrop now if we added like this they would always be rendered i only want to render them if modal is open is true if that state has a value of true now we are changing the state here to use it we can simply output a dynamic expression down here and check if modal is open is truthy like this and then write a ternary expression where if this is true we render modal and that might look strange but that is code which you can write else we don't output anything so we render null this certainly looks strange but that is how you can render content conditionally with react and jsx in these dynamic expressions between the curly braces you can again use jsx and that's what i'm doing here so i'm checking if modal is open is true and if it is i render the modal otherwise i don't render anything and we can actually use a short trick or shortcut here and use the double ampersand the logical and operator here like this to simply use the fact that in javascript if you use this operator if both conditions are true the second value will be returned so if that is true and that is true and a function a component function will always be true then this component function is output here and that's simply shorter than writing this ternary expression we can now repeat that modal is open check here for the backdrop and with that we only output modal and backdrop if modal is open is true and not if it's false and we do this for every to do component so if we save this file as well now we don't see the modal right now but if we click on delete we see it and now we can't interact with the rest of this page because of this backdrop so that's a great step forward how can we now get rid of that modal though to get rid of the modal and the backdrop now we need to change the state again from set modal is open true to false we need to call set modals open again and pass false as a value the problem just is when do we want to do that we want to do that when the backdrop is clicked or when the cancel or confirm buttons are clicked we don't want to do that if the modal itself is clicked for example now for the backdrop click you could think that on backdrop you simply add on click again and then we add a second function here the close modal handler let's say and there we call set modal is open and set this to false and then we point at this close modal handler here as a value for on click just as we did it with the button in the end but that won't work if we save that and i reload i can click the backdrop the entire day the modal won't close the reason for this is that the backdrop like the modal is our own component these are not built-in components so they don't know the on click prop our own components have to be configured 100 percent by us they have no built-in props which we can use to be precise they actually do but only for some very special cases and not for event listeners like this so if you want to make sure that our on click prop exists in the backdrop component we have to add code to this component function to support this prop and for this we can go to the component function and accept this props argument here this props parameter and then here we can of course work with the on click prop or any other name we want it's totally up to you because it's our component but here we can for example expect our on click prop because i'm setting this here in the to do component and we actually expect a function as a value on this on click prop because in the to do component i do pass in a function in the end i point at a function which means i pass a pointer to the function as a value it for this prop now in the backdrop component we actually want to call this function which we receive on the on click prop when this div is clicked now the div is a built-in component again so it does have on click prop and now we could simply point at props on click as a value here by doing this we would in the end forward the function which we receive on our props here on our on click prop into that div on its on click prop and these names don't have to be equal we could expect our on cancel prop here instead and in to do component rename this to on cancel it's our component so we can name this however we want now if we do that and save all the files if i reload now we can close the modal by clicking the backdrop because now we're using a prop to pass a function as a value and that's a pattern which can be confusing and might look strange at first but keep in mind that in javascript functions are first class objects you can pass them around as values just as you can pass strings and arrays and objects and numbers as values hence you can pass a function as an argument to another function and therefore also adds a value for a prop to another component and then that function which we receive in that component can be executed in that component or as we're doing it here it can be forwarded to yet another element another component now we can use that same approach in the modal component for canceling and confirming there we could add functions like the cancel handler and then let's say the confirm handler and kick off different logic depending on which button was clicked but in this case i'll simply in the end run the same code in both functions nonetheless we can bind the first button with the on click prop to cancel handler and here it has to be on click because that's not a custom component but a built-in one so here we can't come up with any other name and for the confirm button i'll also add on click and point at the confirm handler and now in these functions we can run any code we want in this case though i also wanna just close the modal so again i'll just accept the props parameter here and in cancel handler i'll just execute props on cancel let's say in the confirm handler i'll execute props on confirm and hence instead of defining these functions here and pointing at them here we could have also just forwarded props on cancel here like this just as we did it for the backdrop i'm just showing this alternative approach to make it crystal clear that you can execute these functions which you receive through props you can forward them to other elements if that's what you need to do but you can also execute them anywhere in your components and hence i'm using this alternative setup with these extra wrapper functions at which i then point here and now we got our on cancel and our onconfirm prop which are expected on that modal component so in the place where we use the modal component we should add on cancel and on confirm and here in both cases i'll just point at the close modal handler because as mentioned before here i got no special logic i just want to close the modal with that if we save this and reload we can not just close the model by clicking the backdrop but also by clicking cancel or by clicking confirm and that works for every to do here for all to do is the modal works in the same way and that's therefore another very important building block of react props are important for building reusable components state is important for changing what we see on the screen dynamically for adding or removing elements for changing text on the screen or like in this case for showing and hiding an overlay so now that we picked up those important react basics it's time to dig a bit deeper to dive into some advanced concepts like routing sending http requests and application wide state management and what all these things are we're going to explore that and for this we're going to leave this basic project this basic demo we worked on instead we're going to build this meet up demo application i showed you earlier already and for that i cleaned up my project i removed basically all the imports and all the content from this app file here and index css has some new content you find my updated project attached so there you also find the updated index css file and i deleted all the components now as i just said you find this updated starting state attached and you can therefore then start with that same project in the end here once you downloaded it you need to run npm install again then once that's done you can npm start this project again to bring up that development server again and that will give you a blank page because now we're going to build this project from the ground up and this project will now involve more components than the previous one and it will involve the important concept of routing now what does routing mean consider this netflix example from before again there i went to the my list page to view the items i added to my list now it looks like i visited a totally different page but if you watch this refresh icon in the top left corner you see that it never changes it never goes into that loading mode because actually we never fetched a new html page the page loaded by the browser never changed we always stay on that single page and that's the case for netflix because they also have such a single page application it should also be the case for our project now i want to give the user the illusion of having different pages to which we can navigate whilst actually staying on one at the same page and leaving it up to react to change what's visible on the page the advantage of this approach is that we never have to wait for a new page to be loaded instead we can always stay fast stay reactive because everything is handled by client-side javascript which is faster than sending a new request to a server and that can really enhance the user experience now therefore we want to add something which is called routing to our project we want to add a router a special tool which actually watches changes in the url and then changes what's visible on the screen based on the url so which basically gives us a way of giving our users this illusion of routing and for this i'll actually quit this development server again and install a new dependency a new third-party package into this project we do this with npm install with the npm install command but now not just executed like this but instead we now add a package name thereafter the name of the package which should be installed so download it into this project here and that's the react dash router dash dom package that's a package which as the name kind of implies allows us to add routing functionality to react so it allows us to handle urls and change what's visible on the screen without fetching new html pages simply hit enter and this package will be installed and in package.json you'll see that a new entry was added so that file was automatically updated which means that if you now share this project again without a node modules folder and someone then runs just npm install again that newly added package will also be picked up and installed because it is part of this package.json file now we don't need to do this here because we just did install it so we can run npm start again to bring up that development server again and now we can add routing but what does this mean what does add routing mean in the end it means that we need to add this routing tool to our code so that we have this thing watching for url changes and we need to let this thing this tool know which component should be loaded as a page for which route for which url and for this i'll start by adding a new folder next to the components folder inside the src folder and that's the pages folder you don't have to add this folder and you don't have to name it pages but in the end here this is a good way of differentiating and of separating our components that are embedded in other components which will be stored in the components folder from the components that will be loaded as pages technically we'll build components in the same way no matter how we use them but for us as a developer to have an easier time to quickly find the right component we want to work on i'll separate them into these two folders and in the pages folder we're now going to add a couple of react components which again will be built just like all the other components but which will be loaded by this router we just installed when certain urls are visited and here for this application for this project we're building here i'll add a all meetups js file so a component that will be responsible for loading and displaying all the meetups we have i'll add a new meetup js file and i'll add a favorites js file new meetup will allow us to add a new meetup later and favorites js will allow us to view our favorite meetups because we'll add a functionality that allows us to bookmark to favorite a meetup as a user but step by step for the moment i'll just set up some dummy components in these three files and i'll start with all meetups and i'll name this component function all meetups page you can name it however you want i'll just choose this name to make it clear that this component will be used as a page that's loaded by this router now just as all the other components we built before this component has to be exported and it needs to return some jsx code and for the moment i'll just return a div where i say all meetups page that's of course not the final content but some starting content for now then we can copy this and add it in the favorites file here so this is the favorites page and we want to export the favorites page and here i'll then say favorites page and then save this and copy this into new meetup and name this new meetup page and also use that name for exporting and here we say new meetup page now we got these three page components now we need to use that router package to define when which page should be loaded and for this we first of all need to go to index.js and wrap our app component which we render here with another component for this we need to import something from react dash router dash dom and that something which we import is the browser router like this now it turns out that browser router is in the end a component itself and therefore we can use it as a html element opening and closing tags and wrap those tags around the app component now that is something we haven't seen up to this point that a non-standard component so a non-html component would be wrapped around something but it is something we can do and it is something we are doing here we're going to learn how we make our own components wrapable a little bit later in this course so now we initialize this router package we make it aware of this app and we ensure that it watches our url so to say now as a next step we need to define the urls we want to support and which pages should be loaded for the different urls we do this in the app component now so in this wrapped component in there we return a div and we can leave it like this but now in this div i wanna return or use other components which are also imported from react router dom so we also import react router dom here and here we import the route component so just like browser router route is a component and we use it like a component but the job of the route component is to define different paths in the url we want to listen to and which component should be loaded for these different paths and therefore i will also already import my three page components here the all meetups page from dot slash pages all meetups then the new meetup page from dot pages new meetup and of course also the favorites page component from dot slash pages favorites and now in this div here we can use the route component which i'm importing from react router dom and give it a path prop a path attribute now path takes a string and that will be the path in the url after your domain so in our case our domain is for example localhost 3000 that's our domain of course on a real server after deployment that would be something like mypage.com and now the part after the domain is the path that can be just a slash so no path at all in the end or it can be something like slash favorites or slash products or anything like that so the part after the domain is the path and here we define for which path which component should be loaded and here we can start with slash nothing to handle the default path that we just visited our domain slash nothing and then between these route tags we actually do now add the component that should be loaded like the all meetups page like this because that should be the starting page actually we can add another route here for let's say slash new dash meetup and the path is up to you if we now visit mydomain.com new meetup then the component which we render between these route tags will be loaded and that could be the new meetups page and last but not least we can also define um a route for the puff slash favorites and then render the favorites page like this now we're defining three routes and instead of this content here the actual page component will be rendered if that route determines that the current url matches this path so if we are on mydomain.com new meetup this new meetup page component would be rendered and not the favorites page for example so if we save this and we go back and reload localhost 3000 we should see the all meetups page here but if we go to favorites for example we see favorites page as well but wait a second is this the desired result that we see it as well well it depends in some applications depending on what you build you might want such a nested page so that the page for just slash slash nothing is rendered but also this specific page for slash favorites we see this output because by default react router matches all your paths and it simply checks if the current path includes these paths here and slash favorites includes both slash favorites as well as just slash which is why both components are rendered again that could be what you want but often it's not that's why there is another component provided by react router dom which helps us and that's the switch component we can use the switch component to wrap all our route components like this and with that we tell react router that only one of these routes should be active so at most one of these pages should be rendered if we do that and save this we don't see two components being rendered but we don't see the correct component being rendered either instead for slash favorites we now see all meetups and the reason for this is now how your routes are matched react router by default checks if the path of the current url starts with the paths defined here and because of switch it will then stop looking at the other routes as soon as it has a hit as soon as it finds a match now of course slash favorites starts with just slash and then because of switch it doesn't look any further and therefore all meetups is rendered that's not what we want and we can prevent this by adding the exact prop here on route and setting this to true though you can also shorten this and if you have a prop which you just want to set to a truthy value you can just add the prop name like this so we add the exact prop and set it to true to this first route and the exact prop tells react router that for this route it should not check if the path begins with this path but if the full path matches this path and that's now of course not the case for slash favorites so this will not create a match and it will continue looking and it will ultimately find this route for slash favorites so now we see the favorites page for new dash meetup we see the new meetup page and for just localhost 3000 we see the all meetups page and that's how we can add routing but of course at the moment we're just navigating around by entering urls manually and that's not very realistic in reality we would probably want some some header some navigation bar at the top which provides different links and therefore that is what we're going to add next now let's take care about adding such a navigation bar to our application and for this i'll go to the components folder and add a new folder in there and i'll name it layout because it will hold some general layout components so a sub folder inside of components and in there i'll add the main navigation.js file which is the file that should hold this main navigation component now i added it here in the components folder and not in the pages folder because this component will not be loaded as a page with help of the router but instead we will embed it in the content of our other code just as we did before totally unrelated to the router now in this main navigation component file we can again define our component function main navigation and export it as we're used to and then of course return some jsx content here and here i want to return a header a header component which in the end will then wrap all the the items that should go into this header and here i actually want to have a div first with my logo which in this case will just be some text i'll name it react meetups and then next to the stiff inside of the header i'll add a nav element and here i'll then add an unordered list with a couple of list items where all those list items will be the different links which we have here now when it comes to those links we typically render links by using the anchor tag that's how we do that in standard html we could do this here as well but using that link component that link element has one big disadvantage if we use a link like this whenever we click it a new request will be sent to the server the server here is the server hosting this react application and indeed that server would then reply with our application and there the router would figure out which page to load so a link would work but we sent this request first which is redundant we already are in our running react application and it would be great if we don't leave it just because we want to navigate somewhere hence sending that extra request is not something we necessarily want to do that's why instead of this anchor tag we instead use another component provided by the react router dom package so we again import from react router dom and we import the link component here the link component can be wrapped around our link text just like the anchor tag and it will render a anchor tag in the end but internally react router dom attaches a click listener to the anchor tag and when you click on it it will prevent that browser default of sending a request and instead just parse the url you want to go to change it in the browser url bar but then not send a request but instead load the appropriate component onto the screen just with react and javascript so that we stay on this already loaded page and we don't send this extra request so that's why we add links like this now of course here there should not be some link but a link to all the meetups let's say and to make link aware of the url it should navigate to we have to set the to prop here this is one of the expected props on the link component and here we set a path in this case just slash nothing because that is the path to the all meetups page now we can replicate this and add two more list items where the second one leads to slash new meetup and says new meetup or add new meetup that's up to you of course and on the last link we go to slash favorites and we say favorites or my favorites something like this now we got those links in place and we got this main navigation component we can now use this in the app.js file and there we can now import main navigation from dot slash components slash layout slash main navigation and add this above that switch statement here we can add main navigation as a self-closing tag still if we want to if we save this we'll see some navigation here and if we click those links they work the styling is missing but we got working links we got a working navigation now i want to add some styling and for this we're going to explore a different way of styling our components in the first demo application we built i gave you one css file that contained the styles for all components that works for a small demo but not necessarily for a bigger project there you typically want to have different css files for your different components and hence the css file which i provided to you here is very slim now when it comes to styling the different components it would be even nicer if the styles set up in a specific css file would then be scoped to the component to which they belong so it would be nice if next to main navigation we could add let's say a main navigation.css file and then define the styles in that file that belong to this main navigation js file and they should not affect any other component that's something you often want because in bigger react projects you often work with hundreds or thousands of components and you want to make sure that your styles don't clash with each other now the good thing is that create react app this tool which we used for creating this project gives us a project that has a feature built in that allows us to scope styles to components and that feature is called css modules it's a behind the scenes code transformation which will make sure that we can attach css files to specific components for this we first of all need to name our css files in a certain way we need to make sure that they end with dot module dot css so in this case the file is named main navigation dot module dot css and then in main navigation js we can import from this css file that certainly looks strange and it's not something that would work in standard javascript but since we have this extra build step here which parses and transforms our code before it reaches the browser we can actually import from css and that is what we're already doing in index.js by the way we're importing a css file and behind the scenes that will tell the build process that this css code should be injected into the loaded page as well we can do the same here in main navigation.js but now to attach this styling or this style file and its classes to this component we don't import just main navigation.mo like this but instead we import something for example classes this name is up to you from this file now i named it classes because this something here which we import will actually be a javascript object where all the css classes you define in this css file will be properties of this object and you can then use them in your jsx code to attach those classes to your elements and behind the scenes everything will be transformed such that those class names are made unique per component so let me give you an example we could go to the header jsx element here and add the class name prop and set this not to a hard-coded string but instead to a dynamic value with curly braces and set it equal to classes.header now we can add a class named header because here i am accessing header on classes to this css file and any styles we define in here would then only affect this component here so if i save this and i gave this a red color you see now that's colored red and if i had another header class in another component it would not be red because the styles are scoped as i just explained now the goal is here not to make this red but instead i prepared some other styles for you which you find attached you find the main navigation.module.c file attached and you can simply replace your main navigation.module.css file with mine now in here i defined a bunch of styles for you and therefore we now just have to wire them up to the elements we already added the header class to the header on this div with the logo text you should add classes.logo and that's actually it already and with that if you save this let me zoom out a bit now we got this good looking navigation bar at the top here by the way it's not optimized for mobile since this is not really a css course but i want to focus on react instead but now with that we added this nice navigation bar and we added it such that we have component specific styles which are also scoped to this component now that we added our styling in our navigation bar let's work on the pages let's maybe start with the all meetups page and let's output a list of dummy meetups for the moment before we then make sure that we can add our own meetups now for this i'll go to the all meetups.js file and the goal in there is to get a list of meetups later we will get it from a server by sending a http request for the moment we'll work with some dummy meetups and i then want to output those meetups now for this i'll first of all add a constant named dummy data which we'll replace later which holds an array of dummy meetups now here i'll just add a bunch of javascript objects which hold the meetup data things like the image the title the description text and the address maybe and for this you can definitely also use my code attachments there you'll find some prepared dummy data you can also prepare your own one here i just have two dummy objects which have basically the same content just different ids and different titles but the same image the same address the same description text because of course it's not about the dummy data but about what we do with it now one word about that image i got that from wikipedia you can of course bring your own images here i got this nice looking image here created by thomas wolfe and not by me so just to give him you credits and you can of course bring your own image just make sure that you simply get a url to some image and store that in this image property of your dummy data points now we got the dummy data now the goal is to output that data so for this here in this div or section which we could also use we can add a h1 tag let's say and say all meetups and then below that we want to output this data but of course not as code like this but instead as jsx elements and for this we now need to learn how we can render a list of jsx elements dynamically how we can translate a list of data into a list of jsx elements because it is worth noting that in jsx you can actually render an array of jsx elements like this so output a dynamic expression with curly braces then add an array and in there you could have list items like item one and then as a second item item two and if you do that those are rendered so arrays are rendered correctly automatically by react and that's important to know because that means that if we can translate this array of objects into an array of jsx elements we can output it down there and there is a way for translating an array into an array of different data in javascript on that dummy data array we can call the built-in map method which exists in javascript and map allows us to execute a function here i'm writing an arrow function on every element in that array and it will get this element as an input so in this case the the meetup let's say as i input automatically because this function is called automatically by javascript and we then return the transformed data and the result of calling map then is a new array full of that transformed data and here we could say for every meetup object which we're getting we want to return a list item and hence we maybe actually wrap this all here with an unordered list and in that list item we want to output data about that meetup for example to begin with to output the title so here i'm dynamically outputting meetup title in this jsx code so with that we transform our array of objects into an array of li elements and if we do that just like this and we reload we see this is a first and this is a second meetup so that does work now there is one important note about lists though if you open the developer tools you'll see a warning here that each child in a list should have a unique key prop that is a requirement by react which it needs to update and render lists efficiently i dive deeper into that in my react course for the moment it's enough to know that we should add the key prop here to the list item and then set this to some unique value per item and we have a unique value for every list item here the ids the ids are different for every item so here we can then set this to meetup.id and with that we'll no longer get that warning if we reload so that is how we can render a list of data simply by mapping it and that is how you typically do render lists of data with react but in the end you can just render any array of jsx elements no matter how you derived that array now rendering our list like this is of course not our goal we want to render a more beautiful a more good looking list and for this we could structure our code here differently and add more styling but ultimately i simply want to create a new component here and add component specific styling so that's what we'll do in the components folder i'll add another subfolder next to layout and i'll name it meetups and this holds all my meetup specific code and in there i'll add a meetup item.js file and a meetup list.js file because i want to outsource both the list as well as the individual list items into components because as mentioned earlier it is a good practice to split your components and your application as a whole into small reusable pieces now let's start with the meetup item in that file we create our meetup item function of course as we did before and we export that function and then in here we return a list item and then in that list item i want to have a div in which i render the image and set the source to something and the alt text to something and then that's a self-closing element and below that div i have another div with the content where i have a h3 tag with the title an address tag which is a default html tag where i output the address later and then a paragraph with the description and all this hard-coded text will of course soon be replaced with dynamic data and then below that we can add another div with a button where we say two favorites so that this adds the item to our favorites later that's the general structure i want to have here now as mentioned title address and description and also the data for the image should be dynamic i don't want to hard code it here instead it should be passed in from outside from the so-called parent component so the component where we use this component in its jsx code and we learned how we can make that happen we can accept props here and use props and then for example for the image source we could set this to props dot image expecting an image prop on the meetup item which holds that url that should be set as a source here and the same for the alt text that could be our title the title can also be used down there so that we output props.title here and for the address it's props dot address for the description it's props dot description and now all of a sudden this component is reusable and dynamic some styling would also be nice and for that again attached you find css files here the meetup item.module.css and the meetuplist.module.css files which you can copy in next to these javascript files and then in meetup item.js we want to import classes from dot slash meetup item.module.css and assign a couple of classes in that javascript file on the list item for example we'll add the item class like this on this div which is wrapped around the image we'll add the image class like this on the div which is wrapped around the title and description and so on we'll add the content class and then down there for the button i'll add a class of actions like this now that's not all i also want to work on that meetup list component already so here we can again create another component meetup list and export that as a default also accept props here because i expect to get that list data from outside as well and i'm expecting this because i'm the one building this app we could also write the code for fetching meetups in this component but i instead want to make this component reusable and not care about the data source in here but instead just expect that i get meetups through some prop and then it's the component which uses the meetup list component that has to worry about getting the meetups and i'm setting it up like this because i plan on using the meetup list component in the all meetups component and also in the favorites component later and there will have different data sources but the same way of displaying the data and that's what we can make work by adding a separate reusable component in here i also already want to import classesfrom.meetuplist.module.css and return an unordered list here which receives a class name of classes.list which is one of the or the only provided css class for this component and inside of the unordered list here i now want to output my meetup items in the same way as we did it in all meetups by mapping an array of objects into an array of jsx elements just that the jsx elements will now be the list items and for this here we again add a dynamic expression with curly braces and we can expect that on our props here in meetup list we get let's say a meetups prop the name is up to you because it's your component this could also be named items but here i'll go with meetups and then i map every meetup into another object into a jsx element to be precise so therefore using the arrow function shorthand syntax here i'll transform every meetup into a meetup item and for this you need to add this import it was automatically added for me here by the ide if that does not work for you just add it manually and import meetup item from the meetup item file now we render one meetup item per object in the meetups array and that now needs to be configured it needs this key prop this special prop react expects one of the very few special props that are built into react and that can be used on any component including your own components without you writing any special code for it inside of your components so you can't just add that anywhere and we set that equal to meetup.id then in my own component i'll actually pass in the id as well as a id prop we will use that later for the favorite feature i'll pass in the image prop with meetup.image let me reformat this to make it a bit more readable add the title prop and point at meetup.title and also add address and description so meetup.address and description is equal to meetup.description now alternatively we could have also just passed in a meetup prop or any other name and just passed in the meetup as a whole then we would have to destructure it inside of the meetup item component it's up to you which approach you prefer here i'm passing in individual props with all of that done though we can go back to all meetups and now use the meetup list component instead of the unordered list so we go up and we import meetup list from going up one level out of the pages folder into the components folder into the meetups folder to meetup list and then just output meetup list like this and very important provides the meetups prop because we're expecting that prop inside of the meetup list component here so set up the meetups prop here and pass in the dummy data array as a value with all of that done if you save all the files you should see something like this now this is not the final look we'll continue tweaking this but it shows that our content is being rendered and that's not too bad but now it would be nice to kind of restrict the the width which we use on the screen and it would also be nice if the individual meetups would look like like cards with a nice drop shadow maybe rounded corners something like that that's what we're going to add next now let's start with that card look in case it's not clear what i mean i mean that look which we also used earlier for the first demo project where we simply have a nice white background and a slight drop shadow and i'd like to have that for every meetup item now we can solve this by adding a couple of css classes in the meetup item module css file and then changing the look of our list item that would work but this card look is so common that we maybe also want to use it in other components of this application and we will actually use it in other components later that's why i want to create a separate reusable component which should act as a wrapper around other components and just give those components some styling which we then reuse and for this in the components folder i'll add a new subfolder which i just want to name ui for user interface the name is up to you of course in there i want to store some general user interface components which don't belong to a specific feature but instead are used in different places of the app and here i'll add a card.js file and attached you find a card module css file which you can simply add next to this card.js file and in the card.js file we'll now create a component as we did it before simple functional component and export it of course and we'll also import the styling import classes from dot slash card dot module css and then in the component function return a simple div where we set the class name to classes.cart now the special thing about this component is that this should now be the first custom component which we can wrap around jsx content because the goal is to use this card component such that on a meetup item inside of this list item we can use card and for this you need to add the import so import card from going up one level diving into ui card and we can wrap card around that jsx content so that we can use the card component like this that's the goal but at the moment if you save all files the result is that you don't see anything and the reason is that at the moment this card component simply swallows everything we wrap and throws it away you could say because this card component just renders a diff and it doesn't know what it should do with any wrapped content now it's such a common case though that you build components that should wrap itself around more jsx content so you could say that you want to inject jsx content into this component that react of course has a solution for this case and this solution again is related to props we learned that we can pass props by adding attributes to an element and that does work but you can also add a special prop by passing content between the opening and closing tags and that content is then exposed under that special prop inside of that wrapping component so here we accept the props parameter again and then between the div tags i want to output props dot children props dot children is a special prop the children prop is a special prop which every component receives by default and children always holds the content which is passed between the opening and closing component tags so this jsx content that is the value stored in that children prop in this case when we use card in this component like this and now i'm just outputting the value stored in children between these div tags and with that if we reload we now have this slide card look and we see a drop shadow here since we take up too much width we don't see it perfectly but we can see it a bit and if we inspect this in the dev tools we see that every meetup item here has this div with the card class the name was transformed because of that css modules feature but it has that div with a card class wrapped around these other divs image content and actions inside of the list item so that wrapping works and that is another very important technique when it comes to composing user interfaces with react components and that's why we also cover it here and we can now use this technique as well for setting up a general layout for this application because i'd like to have more white space around the content here and for this i'll go to the layout folder and add a layout component in there attached you also find a layout module css file which you can add next to this javascript file and then here in layout.js we can create a layout component function and export it as a default and import classes here from dot slash layout.module.css and then in here return our layout and it could be a div with our main navigation let's say so from app.js i'll cut main navigation and remove the import there and instead in the layout component i'll add that here and therefore of course also add a import of main navigation from that main navigation javascript file which is next to the layout file and below that we could use the regular main html element and then use the layout component such that we wrap it around the actual jsx code that should be rendered so we could say that in app.js we want to wrap the content selected and rendered by the router with our layout so here in app.js we can import layout from going up diving into the components folder layout layout and instead of having this useless wrapping div we could use our own layout component for wrapping here and now this content here the actual route content the page component that is being loaded should be rendered inside of this main block and we can again achieve this with props children we can again accept props here and then output props.children here inside of the main element and that will then just forward that content which is between our layout tags so this content here into that main element now here we should also add a class name of classes.main for styling and with that if we save this now we're utilizing this nice layout component for wrapping all our content it's technically not required we could have added the styling in another way too but it is another nice practice of this children concept and it removes some extra code from our app component and make sure that this component can focus on one main thing rendering the routing configuration because your components typically should be focused on one thing and now we got a leaner app component and we're again using props children to create this layout component here now that we're able to render a couple of meetups there with help of our meetup list and meetup item components it would of course be good if those meetups would not come from our dummy data source but from an actual server and they should actually end up on that server because we created them on the add new meetup page after all that's the goal of this demo application that on this ad page we have a nice little form for entering data about a meetup so entering this kind of data in the end and then that data should be sent to some server to some backend where it's then also stored in a database so that then it can be fetched and loaded in all meetups by doing that meetups that are added here could be shared with all visitors from all over the world since data is stored in a database on some backend server not just in our browser and the data would also be there if we reload the page if we just store data in memory any data is lost if we reload the page because the javascript application restarts and the previous state is lost and therefore the first step is to add this form to this add new meetup page so that then in a second step we can gather the entered data and send it to a server and for this we'll work in this new meetup.js file which is the file that should render this meetup form so in here i'll actually also add a section and the h1 title of add new meetup but then below that i want to output the meetup form which i will actually create and store in a separate file to again keep this new meetup page lean now a good folder would be the meetups folder in the components folder and therefore in here we can add a new file the new meetup form file for example newmeetupforum.js now attached again you find a styling file for this file the newmeetupforum.module.css which you can just download and add next to this javascript file so that you have some styles which i prepared for you and in the new meetup forum js file we now create another function because we're going to create another component the new meetup form function and component which just as before is exported here to make it available outside of this file in the new meetup page component below this title we can then already add that new meetup form make sure you also add the appropriate import now once you did add it back in the new meetup forum js file we can start with outputting the jsx code for the form now i want to actually wrap this form again in this card to give it this card look and that's why i created that separate card component before so that we can now reuse that component so now besides using the card component in the meetup item component we can also use it in the new meetup form simply by using it here and of course by importing it you always need to import what you use in a file from the ui folder and the card file now card will then be wrapped around the actual html form that will create and then will well populate that form with various inputs now i did provide that css file for the form so let's also already import classes from dot slash new meetup forum dot module.css to have these scoped styles and we can start assigning classes on that form element where you should assign the form class like this now inside of this form you can of course structure this however you want but to fit the styles which i provided to you i'll add a div with a class of classes control and in that div i want to have a label where we say meetup title for example for the first input we're going to add now that input is added here and it's of type text it should be required so that we have that in browser validation and i will give it an id of title and then self close it and now connect this label to this input by adding the four attribute but just as class 4 is a keyword in javascript and therefore the actual property name for setting this for value or for setting this attribute here is html4 so i add html4 as a prop and that's another exception besides class name where you use a attribute name that deviates from the regular html attribute name it's basically the only other important exception besides class name which you have to memorize and then we point at tile here and this simply connects this label to this title for screen readers and other assistive technologies now we have this input with this label here and we can now repeat this entire control div multiple times to also render a label for the meetup image and maybe use an id of image here and change this to type url since the image set here should actually be a url pointing at the image if you're interested in uploading files with react that is not really that much of a react task but mostly a back-end server task and hence i discuss file uploads in my node.js course for example but to learn how to make file uploads work with react i also have a resource attached a tutorial which you can take a closer look at to learn how to upload files with react here will not upload files will just insert the url of a existing image which already exists on some server then we can whoops replicate this div again for our address here let's say and the id could be address and here we'll again just have some plain text as an input type and thereafter i want to have one more control which is the actual description of the meetup and hence we could use description as an id but here i'll actually not render an input but instead a text area which is another default html element it'll still get that id description here and it will also still get the required attribute for adding this in browser validation and i'll set rows to five that's another default attribute which we can add to text areas now last but not least below that i'll add another div with a class name of classes actions and in there i want to have the button that submits the form so here we can add a button where we say add meetup and that button will then submit that form that's how html in the browser works if you have a button in a form a button which is not of type button so if you have a regular button like this then such a button will submit that form and we can later listen to that submit event and this should be actions as a class here and with that if you save that file you should see this form on the screen now the form doesn't work yet but it's there now to handle the form submission we got to do two main things we have to listen to the form submission and we then actually have to prevent the browser default which is that it sends a http request automatically and hence it would reload the page we want to prevent this and instead handle the submission with javascript with react and in addition to that we of course need to read the entered values we need to get the actual input the user entered now let's start with the forum submission to listen for that submission we can add the onsubmit prop on the form because by default a submit event will be emitted if you have a button in a form and that button is clicked and we can then catch this submit event here and run our own logic with help of that onsubmit prop now i will add another nested function in the new meetup forum component function let's say the submit handler which should be triggered when the submit event occurs by connecting function and onsubmit like this but as i mentioned a couple of seconds ago the default behavior of the browser would actually be that it sends a request to the server serving this page automatically and we don't want that we don't want that browser default instead we want to prevent that default and run our own javascript logic that might then still involve that we send the http request later but we want to send that request behind the scenes without reloading the page which is what would happen if the browser does its default thing now thankfully preventing that browser default is simple we will get an event object automatically here because all those built-in events like on click on submit and all the other events to which we can listen for all those events react will automatically pass an event argument into the function that is executed for those events this argument which we can accept here as a parameter and this event object will have a prevent default method which we can call to prevent the browser default that's actually not even react specific this event object and this method that is vanilla javascript which is fully supported by react so that will prevent that browser default and will allow us to fully handle the submission with just javascript and react so that's step one now we need to find a way of reading those entered values for reading the entered values we got two main ways of handling this we can use use state again and add the on change event listener to all those inputs which will in the end trigger a function for every keystroke and then we can extract that value the user entered from the event object which will receive for that event and update our state for that given input with the entered value that would allow us to keep track of what the user entered with every keystroke but here i'm actually only interested in the user input once when the form is submitted and for this we can use another concept built into react the concept of refs now ref stands for reference and react simply allows us to set up references to dom elements so we can get direct access to dom elements to set up such a reference such a connection we first of all have to import the use ref hook from react so just like use state that's another built-in special function offered by react which we can execute in our functional components and we can execute use ref here and with that we create a ref object a reference object we can store this in a constant and we could name it title input ref because my first ref here should be for this title input now to connect this created object to this input we add another special prop to this html element another special prop besides the key prop which is built into react and supported on all elements out of the box and that's the ref prop we add the ref prop to this input and as a value we point at this title input ref this will establish a connection and will give us access to this input element through this ref object so here in this submit handler we can then get the entered title so the concrete value the user entered by using that title input ref and then they're actually dot current all those ref objects created with the usrev work such that they have a current property which then holds the actual connected value and therefore it's not current which then holds this input element object the javascript representation of that input element and all those input elements have a value property that's just how javascript works the javascript object representing an input element has a value property and that value property holds the currently entered value of that input so that's how we can extract what the user entered we could also change it we could set value to some new value but we shouldn't really do that if you want to change what's output on the screen use state for that instead but for reading input for reading values refs can be a very useful tool and here we are reading what the user entered now we can repeat that for the other inputs simply by creating more refs you can have more than one ref per component so here i also create the image input ref like this and i'll already copy that a couple of times and also create the address input ref and the description input ref and then we connect those refs with the ref property here on the image we connect this to image input ref for the address we connect this to address input ref and on the text area which is there to enter a description we connect the description input ref now with that we can extract all those entered values in the submit handler so we get the entered image with whoops with image input ref dot current dot value we got the entered address with the address input ref.current.value and we got the enter description by using the description input ref current dot value and that then allows us to create a new object let's say the meetup data object which then has a couple of keys like let's say title and stores those entered values as values so the entered title for the title key for the image key i store the entered image for the address key let's say we store the entered address and for the description key we store the entered description and now for the moment i'll simply log that meetup data with console log soon we will send it to a server instead but for the moment let's just see if that works and hence if i now go back and open up the devtools here and reload we can enter something here like uh test and then here's some url let me just grab that dummy image url from my dummy meetup data in the all meetups.js file and insert that here without quotes some test address five one two three four five test city and then this is a test and if we now click add meetup we see this object here on the right which is the object with all the entered data so submitting the form and handling the submission preventing the browser default and gathering all the user input all of that works now and that is how we can handle forms with react now of course the goal is not to just lock the data here though instead we now want to send it to a server which then stores it in a database so we want to send our meetup data to a server this course is about react about the front end and therefore here we will not write any server-side code or create our own backend i do have separate tutorials on that got my node.js course where you learn all about that back-end technology including how to connect to databases how to create rest apis and much more and i got a free tutorial as well where we also build a rest api in detail with nodejs step by step because with react or with single page applications in general you typically need a backend api to which you can send your requests so a backend which does not send back html but which instead expects data in a certain format typically json format and which then returns data in that json format and which simply exposes a couple of urls to which you can send requests and depending on which url you're sending a request to different things will happen that's the kind of backend you typically connect to with react now you don't connect a front-end application like react or angular to a database itself i got a full tutorial on that where i explained why we don't want to do that you also find a link to that attached you don't connect directly to a database with react and so on because of security all the code you write here in your react application in the end is exposed to the visitors of your page through the dev tools if i look at sources if i dig into that i can read the javascript code that makes up your application it might look a bit different than when we wrote it but all the code is in there and database credentials would be in there as well that's why instead we need a backend api a backend server to which we can send requests and then it's that server which on the server connects to a database and stores data in a database and hence that's what we're going to do here now as i mentioned though we're not going to write our own api instead we're going to use firebase as a dummy backend here firebase is a service offered by google it is actually made up of a bunch of different services but it is a service which you can get started with for free you just need a google account and it is a service which contains a database and an api to which we can send requests which will then ensure that data is saved in that database and for this i'll therefore log in here with my google account and then once logged in we can create a new project here you can enter any project name you want here i'll just name it react getting dash started click continue you can disable google analytics we don't need that and create that project now as i said firebase is a service which has a bunch of built-in capabilities here we'll just use it in a very basic way to have this dummy back-end to talk to and i'm using this back-end this service because that allows me to show you how you send requests to a back-end and you would then do that in the same way no matter which back-end you use in the end that's why that's a good service to use now here we want to use the real-time database which is one of the features firebase offers and then there click on create database now you can leave the default region and make sure that you start in test mode not in locked mode otherwise you'll not be able to send requests now this sets up a database and very important also immediately an api to which we can send requests we can use this url here to send requests to and behind the scenes on firebase servers those requests will then be parsed and depending on which kind of request we send data attached to the request will be extracted and stored in the database automatically and therefore it can look like if we're directly sending requests to a database but we're actually sending requests to that firebase api which then behind the scenes stores them in a database and therefore that's the url to which we now want to send a request when we submit that form now it's up to us where we want to send that request if that's in the meetup form component or maybe in the new meetup page component and since the new meetup forum component is already quite a big file i will actually not add the http code here but instead in the new meetup component code so in the new meetup form component i just want to forward that meetup data to the parent component to the component where we use this component and we learned that we can do that with props we can accept props here in a new meetup form and then instead of console logging the meetup data we can expect that on props we have some prop which actually gets a function as a value a function which we can then call from inside here let's say the on add meetup prop the name is up to you because that's our component i expect that the value on this prop is a function so we can execute it here and i'll pass meetupdata as an argument now of course for this to work we now need to make sure that in the new meetup component we now add this on add meetup prop and that the value we pass in here is a function so here i'll add a new function the add meetup handler function which expects to get some meetup data because i'm passing that argument here when i call the function from inside the new meetup forum component so i expect that data here and i then pass this add meetup handler function as a value to onad meetup like this without parentheses just pointing at it now in this function that's where i want to send a http request now for sending a http request we can use the fetch function that's a default javascript function built into javascript it has nothing to do with react it's a standard javascript function supported in modern browsers and it is a function that allows us to send http requests we could also use third-party packages like axios which is also a popular library for sending http requests but i don't want to install an extra library here so i'll stick to fetch now fetch wants an argument and the first argument should be a string it should be the url to which we want to send a request and here that's that url which we get from the firebase real-time database console now this firebase real-time database service works such that this url can be manipulated we can add segments after this domain and then these segments will be translated into folders you could say in your database into tables you could say so we could send the request to this url slash meetups and that would add a meetups table a meetups collection to that database here and hence i'll do that here now one special thing about this firebase api is that you need to add dot json at the end here that's not react specific that's just something firebase requires and with that that is the url to which we're sending our request but here i actually wanna store data on firebase servers and to signal to firebase and to this api that we want to store data we actually must send a post request and by default fetch sends a get request and that will always depend on the api you're working with but most apis are built such that storing data requires post requests now to send a post instead of a get request we add a second argument to fetch here and that second argument is an object which allows us to configure this fetch function call and this http request therefore and here in this object we can for example set a method property to define the http method that will be used and here we can set this to post instead of get which would be the default so here we use post instead now when we send a post request we should also add the data to the request the data which we want to store and we do that through the body field which we add to this second argument to this configuration object now body wants the data we want to append and that data should typically be in json format which is a very popular the most popular i would argue data format for transmitting data with http requests and in javascript we can easily create json by using the built in json object and calling the stringify method and to stringify we can pass default javascript objects or arrays or values in general and they will be converted to json so here we could pass our meetupdata object which we're getting as a parameter as an argument to the stringify method now last but not least we can add some extra headers if we want to and for example add the content type header and set it to application json to add this extra metadata to the outgoing request and make it crystal clear that this request carries json data some apis also require this and with that we're sending such a post request we can do more with fetch we can listen to the success and error cases and we do that in the full react course which i offer but for the moment here this is actually enough because this will already send a post request with our data to firebase and hence now here if we save this and i click on add meetup now with data entered we don't see any feedback here we'll work on that in a second but if we go to firebase we see that there is a new meetups node and in that node we got this cryptic id here which is actually auto-generated by firebase and if we expand this we see our submitted data so storing that data on firebase servers works now let's work on the feedback which we provide to the user here when we add a meetup to give the user some feedback that it worked we probably want to navigate away from this page once the request was sent and previously we navigated through these links which we added to the navigation here now we want to trigger navigation programmatically so once we're done with a certain task in this case once we're done with sending a http request thankfully implementing this is also simple with react router we can simply import something from react router dom and that something is another hook the use history hook so react has some built-in hooks other third-party packages also can provide their own hooks you can also build your own hooks but we're not going to do that here in this course but here we've now got this use history hook and we can call this hook here in the new meetup page component function now this gives us a history object and that's simply an object which exposes certain methods to us that allow us to manipulate the browser history to navigate away for example now here let's say we want to navigate away after the data was submitted to achieve this we can use the fact that fetch returns a promise which resolves as soon as this is done and hence we can add a then block here and define a function which will execute when the problem is completed and it's then in this function where we want to execute history and then some method that allows us to navigate away for example the push method to push a new page onto the stack of pages in that case we could then later use the back button to go back to the previous page and since that doesn't make too much sense after submitting a form i'll instead use the replace method that will navigate us away but it won't allow us to use the back button to go back to the previous page and here i just want to navigate to the starting page with slash nothing so in the end we pass to replace what we also passed to link to the to prop here we set up the destination the target destination of a link with the replace and push methods on history we also pass the target path as an argument now now instead of then we could also use async await here by the way if you wanted to now with that we're navigating away once the request succeeded and therefore let's now give this a try let's save this and enter some new data i'll repeat using that image here that dummy image url some other address and some other description here and then i'll click on add meetup and you see that i'm now navigated away and going back won't get me back to that forum and on firebase we of course now also have that second meetup added here and that's how we can navigate programmatically and leave that add new meetup page once we're done now let's make sure that the meetups we show on the all meetups page are actually the meetups stored on firebase because at the moment that's not happening so let's now make sure that we load the data we store here on firebase into our application into our website here when we load this starting page because at the moment here in the all meetups page we're still using this dummy data and that's of course not the goal now to load data from our back and from our api we need to send a http request again just as we send one when we store data so in the all meetups js file in the all meetups page component we want to send a request the question is when do we want to send the request and the answer is whenever this component is being rendered so whenever we visit this page so what you could do what could be your first idea is that directly in this component function before we return the jsx code we can fetch our data we can use the same url as we used for storing the data since we want to fetch data from the same api and node and hence we can use the same url here now we don't need to configure this request here with this second argument because the default is that a get request is sent and that's exactly the kind of request we need here we want to send a request to get our data so we can call fetch just like this and this will fetch this data but now unlike as with the post request when we send data now when we get data we are definitely also interested in the response now since fetch returns a promise we can of course use the then method here and chain this after then to handle this response so we pass an anonymous function to then and here we'll get the response object as an argument automatically because that's how the fetch function works it returns a promise which resolves to the actual response at some point in time now from that response we want to read the body we want to read the data and we can do that with the json method that's a method which exists on this response object out of the box and this will give us access to that data automatically converted from json to a plain javascript object but here's a gotcha json will actually return a promise as well so we also need to wait for this promise to resolve so i actually will return response json here and add another then block where we then get the actual data and it's now in this second then block where we can work on that data we could also add error handling and we do that in the complete guide course but for the moment here let's focus on just getting that data and using that data so here in this then block we get the data what do we want to do with this data now in the end we want to extract an array of meetups from that response data and pass that as a value to the meetups prop on the meetup list now we'll have a problem here though since fetch returns a promise and we're in this promised chain javascript does not wait for this promise to complete before we return here now you could think that we can use async await here to wait until this is done but that would be bad because that would mean that the entire component function now returns a promise because that's what the async keyword does it converts this function to a function that returns a promise and that then no longer qualifies as a valid react component because react component functions must be synchronous and must not return a promise but instead they have to directly return jsx so we can't use a single weight here hence we can't defer returning a value until we have a response instead what we need to do is we need to return some temporary jsx code for example a loading spinner or something like this and then once we have the response we want to update the returned jsx code and how do we change what's visible on the screen with state that's what we learned earlier already we can use state to change what's displayed on the screen when certain conditions change before we did that when the user clicked a button and we wanted to show an overlay now i want to change the state once we have response data so for that here in this all meetups.js file we can import use state from react so this use state hook and then register some state here with use state and here we could for example set up some loading state so name the constant loading or is loading and add a set is loading state updating function because you learned that use state always returns an array with exactly two elements where the first element is the current state snapshot and the second element is a function for updating the state and when we have data we wanna set is loading to false again because we're not loading anymore but actually the initial state here should be true not false so we start in a loading state and then we set it to false once we have the data and then with that we could check if we are loading here in the component function before we return i check if we are loading and if we are then i want to return another piece of jsx code where i for example have a section with a paragraph where i say loading something like this so that's my fallback content which i want to return in this component whilst we are loading and we only return the actual meetup list if we're done loading so if we have the data but speaking of that there we're missing an important point at the moment we're just managing the loading state we're not doing anything with the actual data that is being fetched for this we could add another state to this component and that is something we haven't done before but you can have multiple pieces of state in one and the same component as many as you need there is no restriction here and this could be our array of meetups and it could be an empty array initially but eventually we want to override this once we fetched our data from the backend from the api so here i'll name this loaded meetups and set loaded meetups and here we want to set loaded meetups to data let's say that will not be the final step but for the moment we can do it like this and then we could pass the loaded meetups instead of the dummy data to our meetups prop down there and that means that now we can also get rid of that dummy data so i will delete this dummy data constant now don't save this file yet though because this code will cause an infinite loop what's the problem here the problem is related to state and our http request you might recall that i mentioned when i introduced state that when we call this state updating function we tell react that it should re-execute this component function and re-evaluate it and then return the updated jsx code that's the idea of state it allows us to re-evaluate a component and possibly render different content on the screen whenever state changes the problem here is that we change state once we made our request we change the loading and the loaded meetup state then this component function will execute again what does this mean it means that this fetch function will run again and we send another request and once that's done we update the state again which means the component function executes again and fetch is called again and so on and so on so we have an infinite loop and that breaks our application and spams our api with requests and it's not something we want how can we prevent this so how can we work around that problem this is such a common problem and such a common scenario battery act has a solution for it there is another hook which we can import from react and that's the use of fact hook user fact is a hook that allows you to run some code under certain conditions at the moment this code for ascending the request runs always when the component function runs with use effect we'll be able to restrict this and define conditions when this code should run so that it does not always run for this we call user fact we execute this user fact function directly in our component function and then use a fact once two arguments the first argument is a function and here i will pass in an anonymous arrow function the second argument is an array an array of dependencies and i'll come back to this array in a second now inside of this first argument inside of this function we can execute our batch code here so i'll cut this and add this in it into this effect function now this effect function this first argument here which we passed to use a fact will be executed by react on our behalf but only under certain circumstances not always when this component reruns i'll come back to those circumstances in a second now with that we make sure that our fetch request here our fetch function is only executed when react executes this function now when does react execute this function though if we would not specify this second argument this array if we would omit this then this effect function would execute whenever this component function executes so then we don't gain anything that's why you need this second argument you technically don't need it it's not required but if you omit it there is no difference compared to just running the code in the component function with this second argument added though react will check the values you add to this array and compare them to their equivalents when this effect function was executed the last time now if that's an empty array there are no dependencies and then react will only execute this function when this component function rendered and executed for the first time and for subsequent executions of this component function this effect function will not run because we have no dependencies so the values of the dependencies are always the same because there are no values now if you would add a dependency here like let's say the is loading state snapshot which you should not but if we would have this as a dependency here then this function would execute whenever the value of is loading changed so if that value does not change if that always stays the same then this would also not execute again but if is loading was false and then you somewhere update its state to true then the value of is loading would have changed and then this effect function would execute again now in reality you don't need to think which values should trigger your effect function instead there is a simple rule in your dependencies array you should add all external values your effect function relies on so in this case there are no external values the fetch function is a built-in browser function it's not one of our component props or state and other than that we don't use any state or prop values in this effect function that would belong to our component if we would extract some data from props here though if we would for example get the url from props url let's say then props would be a dependency and we should add props here but that's not the case here but that is how it would work then set is loading and set loaded meetups actually technically would be external dependencies because these are constants defined outside of this effect function but these state updating functions are an exception you can add them here and that would not be incorrect that these functions are external dependencies and whenever these functions change this effect should run again because then these functions might do different things than they did the last time they were executed but react actually guarantees that these state updating functions will never change they will always do exactly the same thing and therefore it's allowed to omit these functions here and hence in our scenario here we use user fact like this with an empty dependencies array since we have no external dependencies here and therefore this code will only run once when this component is rendered for the first time now i dive way deeper into usefact with more examples and also more features of this hook in my course but what you learned here is the core foundation of fact which you have to understand that you can use it for running such side effects as they are called code which does not directly influence what's showing up on the screen and that for such side effects user effect is the proper solution for controlling when this code should run now with that we actually should also set is loading to true here at the beginning of this effect function so that whenever this effect would run again we set this to true again it doesn't run again here but still that is cleaner i would argue and then we send this request and ultimately we update our loading state again and we set our loaded meetups to the data we fetched here and now with that it still won't work because setting the data like this is incorrect as it turns out but we don't have an infinite loop and i hope i could make it clear why that's the case if we now save everything our app crashes because as i said we're setting the wrong data but we don't have an infinite loop so now what's wrong with that data though the problem with our data is that when we fetch meetups from firebase we actually don't get an array instead we get an object where these cryptic auto-generated ids act as properties so when we send a get request to our firebase api we get back an object with two properties in this case and these here are our property names and then nested inside of these properties we got nested objects with the actual meetup data now here in our component though we expect an array because in meetup list we map on our data and that only exists on an array not on our object hence we need to transform the data here in all meetups before we set our state once we fetched the data so in this second then block here we want to transform the data we can do this for creating a helper array here meetups like this and then a four in loop where we go through all our keys in data so all the keys and this data object we fetched from firebase and these keys will be these random ids here these unique ids that will be our keys and then we create a new meetup here for every key through which we loop so for every meetup that's stored on firebase and we can set the id equal to key since that is that auto-generated id and then just distribute data key into this object so we access the nested object for the given key so we access the nested object here and then we just use the spread operator which is a default javascript operator to copy all the key value pairs of this nested object into this object and that constructs a meetup object as we need it and then we just need to push that onto our helper array here and then it's this helper meetups array which we want to set as our loaded meetups data and now if we do that if we transform the data like this if we save this and reload we see loading briefly but then we see all our meetups and that's how we can fetch data in this case from firebase but in general with usefact fetching data with a loading and a data state without causing an infinite loop now that we can add data to firebase so that we can store data on our server and that we can fetch data whenever we visit all meetups now with that we got the core functionality built in the last feature which i want to add here is this favorites feature this button here should be clickable and when we click it this meetup should be added to our favorites then on the my favorites page i want to see a list of all my favorites and of course as soon as an item is a favorite i want to be able to unfavorite it and then i also want to show a little badge here in the navigation next to my favorites where we see the current count of favorites that's the last feature i want to add and for this we'll need to manage some state which affects more than one component because our list of favorites is some state that should cause the ui to update because we for example will have that badge here which shows the current number of favorites and of course this button should change once item is a favorite so we'll have different parts of this application that will be affected by our state and because that's the case because we'll have a state that affects more than one component we will need a mechanism of managing that state globally and distributing that state to different components because just using use state inside of a single component doesn't necessarily do the trick anymore because that only affects one component now one thing we could do is we could lift the state up that means that we could for example manage our favorites state in app.js and then we pass it into all the components that are interested as props so to the layout component which has access to the main navigation component which is where i want to show this batch in the end to that component we could pass the number of favorites if we manage the favorites state in the app component and then to the favorites page component we could pass the array of favorite meetups so we could manage the state here in the app component and then just distribute it through props that would work but it has a couple of downsides one problem would be that if we have a bigger application with different states that affect different components we have to manage more and more state in this app component and hence this app component becomes bigger and bigger and that's maybe not ideal another problem is that if we pass state down through props that we can end up with very long prop chains we pass the number of favorites to the layout component and from there we pass it into main navigation so we already pass props to layout just so that this component can then pass that data on to another component whilst that is not horrible it's also not necessarily great and it can also make our code a bit harder to maintain and because we have issues like this there are state management solutions for managing application-wide state in a more convenient way one very popular state management package is redux i cover it in my course but for many scenarios we don't even need redux because react also has a built-in state management solution for application wide state and that's a feature called context now for this to add this context feature i'll add a new folder in the source folder and i'll name it store the folder name is up to you but store is a common convention since we will set up the state store for this application inside of store i'll add a favorite stash context.js file and in this file i'll now create such a context for this in this file we first of all import create context from react so that's a function exposed by the react library and we can then call create context and this does what the name implies it creates a context we don't know yet what exactly such a context is but hey we are creating one at least now context in the end is a javascript object and we can store this in a constant and i'll name it favorites context i start with a capital f because this object which is created by context actually will contain a react component and when you build your own react components the convention which you should follow is that you start with a capital character for your component names so that's why i store my context in a favorites context constant here now create context also takes an argument and that argument is the initial value for that context so the initial value for this application or component-wide state and that can be any value of your choice it could for example be an object let's say an object where we have a favorites key which is an empty array initially because we have no favorites at the beginning and maybe a total favorites key which is zero initially which is the total number of favorites that could be our context but like this it's not too useful we also need ways of changing these values of adding and removing favorites and that's why i will also add a component in this file so a component function which i'll name favorites context provider this component will be a regular react component but it will have the job of providing this context to all the components that are interested in listening to the values so all the components that need values from the context and this component here the favorites context provider component will also be responsible for updating the context values now for this what we'll do here is we'll return favorites context so this constant which we created here dot provider that's a component this context object has built in and this provider component needs to be wrapped around all the components that are interested in interacting with that context now this favorites context provider component which we are building here itself should be wrapped around other components later i plan on using it in index.js to wrap it around my entire app so that all the components in the app have access to the context and therefore what we can do here is we can accept props and simply wrap this provider component which we get from this context object around props children that means that we can now wrap our component here around any other components and those components will be wrapped by context automatically i hope this makes sense now why am i doing it like this because now in this favorites context provider component which we're building here we can manage our context data we can manage that with state because this component which we are working on here is still a regular react component so when we manage state and air when we change that state that component here will still execute again and will be re-evaluated and that means that if we change our context value in this component and we pass this context value to the provider all components that are listening to our context will be updated and we'll get that latest updated data and in case it's not 100 clear yet we'll get there step by step because we're now going to add the logic for this in favorites context provider i'll create a context object and i'll pass this context object as a value to favoritescontext.provider this component which is exposed by this favorites context object wants a value prop where we pass the current context value we set the initial values here when we create the context but we can then update those values and pass the latest values with help of that value prop and whenever that value changes all components that are listening to our context will be updated in the end that's how this works so now we just need to derive this context object and its values dynamically and that's where use state comes into play now we can manage some state here in this favorites context provider and we can manage an array of favorited meetups here so here we have the user favorites let's say and a function for setting those user favorites here this context object which we construct which holds the latest values that should be exposed to our components that object now has a favorites key because we defined that here in the initial context value as well and we set our current user favorites array this state snapshot as a value so when the state changes this value will change and we'll have a new context object and will pass this new updated context object to all the components that are wrapped by this provider in the end and i'll also set total favorites here and that is simply user favorites.length like this now we just need a way of changing our state here and of course we can do this with functions we can add a function that's called the add favorite handler for example and a function that we could call remove favorite handler and i will also add a helper function which i'll name item is favorite handler that's a function which will later help us determine whether a given item is a favorite or not now in the add favorite handler item i expect to get my favorite meetup as a parameter and then in there i want to set my user favorites to the old array plus this new item now for this we could use user favorites dot concat and add the favorite meetup concat is like push but returns a new array and it's then this new array with that added meetup which we set as our new state but there is a gotcha we should not do it like this even though it typically will work when working with use state it is worth knowing that react actually does not process state updates instantly but it schedules them behind the scenes and it still then processes them very quickly but not instantly necessarily now because of that when you update your state and your state update depends on the latest state snapshot there is a scenario where the state snapshot does not really reflect the latest state because the last state update wasn't processed yet and because that is the case there is an alternative form of calling this state updating function if you depend on that last state snapshot instead of passing the new value as i did it a second ago you should pass a function to the state updating function and that function will be executed for you by react that function will then automatically receive the previous state snapshot so the previous user favorites here and you should return the updated state here so in this case previous user favorites where we then concat the favorite meetup we get as a parameter this will guarantee that we always get the latest state snapshot here because react will execute these functions which we passed to the state updating functions in the correct order so now we have a guarantee that we definitely work on the latest state snapshot here and that's therefore the better way of updating your state if you depend on a previous version of that state and that's now how we could add a favorite item now in remove favorite handler we probably can expect a meetup id which identifies the meetup that should be removed and then we can update user favorites again with this state updating function where we get the previous user favorites and return a new state snapshot because here again we rely on that previous state and here we then want to return previous user favorites filter because filter returns a new array where we can filter out items and i want to filter out the item where the meetup id matches this id we're getting as a parameter filter is a built-in method which takes a function as an argument which executes for every item in this array and we get that item as a parameter then and then we have to return true if we want to keep that item or false if we want to get rid of it in that new array which is returned and here i want to return true if meetup id is not equal to the meetup id i get as a parameter so if it is equal we return false here because of this check and that means we drop the item where the id is equal and that means that the returned array will be missing the item which has this meetup id which is exactly what we need here since we want to remove that item and in item is favorite handler i just want to return a response here a return a value and i want to check whether let's say a item with a given id is part of our favorites and for this we don't need to update any state it's just a helper function where i return user favorites sum which is another built-in method which exists in vanilla javascript and sum also wants a function as a argument which executes for every item in this array and this function should return true or false and if at least one of the items in the array returns true or false with that function some overall will return true or false and that allows us to find out if some item in this array matches our condition here and the condition is that some meetup id is equal to the meetup id we get as a parameter so we return true if we have a meetup with that id in our user favorites now we got these three functions for changing our context but at the moment these functions are never called anywhere they should instead be called from inside some of our other components and pages so actually what we want to do here is we don't just want to manage values which are then accessible by different components but also functions that will change those values that are accessible from different components and hence we can expose pointers at these functions to our different components as well so in our context here we don't just have the values for our favorites but we also can add functions there we can add a add favorite key for example which stores a pointer at the add favorite handler as a value so we don't execute the function here we point at it and that exposes this function defined in this component to all components in this application that are interested and you will see how to use this context in other components in just a second and we can therefore also add remove favorite here and point at the remove favorite handler and add the item is favorite key and point at the item is favorite handler function and now we expose these functions to all interested components as well now that that's the case i will also go to my initial context and add those keys here as well and set that to empty functions that just get the correct parameters and um i'm only doing this because that will actually give us better auto completion later it doesn't really do anything here since these are functions that don't do anything but it will help us with auto completion in the ide later and that's why we'll just add them here to the initial context as well okay so now with that we spent a lot of time in that file and i could imagine that it's not all 100 percent clear yet but we're now done with working in this file now we need to wrap our context provider around all components that want to interact with this context and then in the different components we need to pull out the values we're interested in or call the methods the functions here we defined and for that we need to export this favorites context provider component here by adding the export keyword in front of this function and also maybe at the bottom of the file export the context itself the favorites context itself as a default so we have two exports this function here which we export by its name and then this default export which is our favorites context itself these two things are exported here because we need to interact with both objects with both things from outside this file now let's start with interacting with this favorites context provider component i mentioned multiple times that we want to wrap this component around all the components that are interested in our context data and in this case the my favorites page will be interested the navigation bar will be interested since i want to show a badge here and the all meetups page will also be interested or to be precise the meetup item components will be interested because there i have this two favorites button which for example should trigger the add favorite handler so i have various components from all over the app that are interested and hence the easiest way of providing the context is probably to wrap everything with it so here in index.js i will import the favorite favorites context provider from the store folder and they're the favorites context file and actually i'll wrap it in curly braces because i don't want the default export the context object here but i want my component function instead this favorites context provider function which i export like this under its name and we import named exports between curly braces that is standard javascript now we can wrap this provider component around the browser router and the app and with that everything all components in this application are able to interact with this context now how do we interact though let's maybe start with the meetup item component here we have this two favorites button i want to make sure that when this button is clicked we add this item to our context and i also want to update the text on the button depending on whether this item is already part of my context or not and actually if it is part of the context already if we already did favorite a meetup item this button should no longer add this item to the context but remove it from my favorites array in the context hence a first step is to add a function in this meetup item component which we could name toggle favorite status handler the name is up to you though and i'll bind this function to the on click prop of this button so that when we click this button this function will be executed and now in this function we will need data from the context we need to find out whether this meetup item is already part of the context or not and then do different things depending on that information now for that we now need to tap into the context and get values from there and we do this with help of another hook provided by react and that would be the use context hook this hook allows us to establish a connection between this component and the context simply by calling use context here and then by passing the context object to which we want to connect as our argument and here i'm not talking about our favorites context provider component but about the context object which we created with create context which is why i'm exporting that as a default as well with this in meetup item we can import the favorites context whoops like this so that default export from going up going up store favorites context and it's then the favorites context which we pass to use context and that now gives us access to this favorites context object so to this object here which we're distributing through the value prop to all the components so to this object to this object we'll have access now instead of meetup item that's the object which is stored in this favorites ctx constant now and now we can for example find out if this item this meetup item here is a favorite by using this favorites ctx constant and calling item is favorite so this method which we defined on our context there as well this method which points at the item is favorite handler function we execute this function now by executing it here in the component like this and we need to pass in the id of the meetup for which we want to check whether it's favorite or not and we get the idea of this meetup through props there is this id prop which we pass into our meetup item here when we render it so we can use props.id to pass the id off this specific meetup to item is favorite and that will return true or false so here we then have that response now here in the toggle favorite status handler we can check if the item is a favorite so if this constant has a true value and if that's the case we know that we want to remove that item from the context now when that button was clicked because it is a favorite already which means now we want to get rid of it so then we use our favorites ctx constant this context object and call remove favorite and remove favorite also wants the meetup id so we pass props dot id here else if the item is not a favorite yet we call favorites ctx dot add favorite and here we need to pass in a new meetup item now so i will construct a object on the fly and simply set my id to props dot id the title to props dot title the description to props dot description the image to props dot image and the address to props dot address and that now recreates this meetup item and passes it as an argument to the add favorite function which in the end triggers this add favorite handler function in this favorites context provider component and that will then update the state there add this item to the user favorites array and because the state was updated it will update all child components because this component here as a whole will be updated and hence the jsx code with all the child components will be updated again and hence all components will have access to that latest state now so that's how we can now trigger a state update to this global state this favorite state from inside the meetup item component we change some state which is not managed in this component but on a global level and now going down to this button we probably want to change the caption depending on whether the item is a favorite or not so i'll output something dynamic here as a caption and check if item is favorite so i'm using this constant here again which has true or false as a value and if it's true then the button should say remove from favorites if it's false so if the item is not a favorite yet the button should say two favorites because then clicking the button will add the item to the favorites and now that was a lot of work but if you did all of that if you save this now you should be able to reload and click two favorites and it should change to remove from favorites and back and forth we don't see the favorites on the my favorites page yet but adding favorites does work as we can tell by this button now let's make sure we also render the favorites on this my favorites page and that we have a little badge here so to output the favorites on the my favorites page we can go to this favorites page here in the pages folder and again tap into our context here because on this page we now in the end want to get all the favorites from the context now for this we can of course import use context again from react and also import the favorites context object from the store folder and their favorites context and then we connect to the context just as we did it before we create a constant which then stores this context object and we call use context and pass this context object we created in that context file to use context and that gives us the current context snapshot then now we got our context here and that means that now from that favorites context we can get our favorites array so in the end here we can now return let's say a section where we say in a h1 tag my favorites and below that i want to output a list of meetups a list of my favorite meetups for this we can recycle the meetup list component because this component does not care whether it's all meetups or a subset of the meetups all it cares about is that we output items that have these properties so we can import meetup list from the components folder meetups meetup list and then output that below the h1 tag meetup list like this and set the meetups prop here equal to favorites ctx dot favorites because that is our array of favorites now if we do that on that favorites page we see all the favorites we have the problem just is that if i remove a favorite we don't see anything here which makes sense because i currently have no favorites but we might want to render some fallback message for this case and one way of doing this is that we define a little helper variable here content and we then check if favorites context total favorites is equal to zero total favorites is another property we're managing in our context and if that is zero we know we have no favorites then i'll set content equal to let's say a paragraph where i simply say you got no favorites yet start adding some question mark else if we do have favorites i set content equal to my meetup list here so in the end to this line of code and this might look strange storing html elements in variables but it's actually not stranger than returning html elements you can use jsxcode anywhere where a value is needed we saw it in arrays in return statements you can also store jsx in variables that is totally fine and now we can simply output the value of that content variable in our returned jsx code to then have different values here depending on whether we have favorites or not if we now save this i got no favorites yet here but if i add a item as a favorite i see that instead and if i remove it we're back to this other text so this works one important note though if i add a item to my favorites and i then reload the page it will be lost the reason for this is that our context is only stored in memory because we're only working with state and with constants here it's not stored permanently if you would want to store it permanently you would need to use some browser storage here in the favorites context provider like local storage for example or store it on a server as well i'm not doing that here because i want to focus on this core feature of react context but that is something you could add if you want to enhance this application for the moment it's simply some temporary storage which survives as long as we are on this page but if we ever reload or leave the page our favorites will be lost our meetups won't because those are stored on a server it's just something that is worth knowing and now with that that's almost it as a last step i now just want to make sure that in the main navigation we also see a badge next to the my favorites text that indicates how many favorites we currently have and that simply means that in the main navigation js file we also want to connect to context and get values from there so i'll again import use context here from react and import my context object the favorites context from going up going up store favorites context and in main navigation we then get the favorites context by using use context and connecting that to the favorites context and then here on the favorites link we can simply add a little extra span next to this my favorites text in which we output favorites ctx dot total favorites because that is a number managed in our context with the total number of meetup items in our array and i'll give this span a class of classes dot badge which is one of the classes prepared in this css file i gave to you earlier and with this we now have this badge here and if we add items to the context that batch does update and also if we remove items of course now that's it for this summary of react we had a look at all the core features that make up react like state and use effect and context and components and props of course and we built this little demo earlier and now this demo project here which uses more features including features like routing and forms of course react has more to offer and you can also dive deeper into the concepts i touched on here a for example use effect has more to offer than what we're using here but that is why i do have a complete course with more than 30 hours on this topic however this summary here gives you all the core features and a good foundation which you need to dig deeper into react and therefore hopefully it's now a bit clearer what react is how it works and you now should be able to get started building your own react project as well
Info
Channel: Academind
Views: 330,845
Rating: 4.9628992 out of 5
Keywords: react, reactjs, react.js, react javascript, react course, react tutorial, react for beginners 2021, react udemy, react academind, react schwarzmueller, javascript library, react hooks
Id: Dorf8i6lCuk
Channel Id: undefined
Length: 231min 56sec (13916 seconds)
Published: Wed May 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.