This video is there to get you started with React.js, arguably the most popular JavaScript library for building modern, highly reactive user interfaces. I do have a complete course on React.js, which of course allows you to dive way deeper into React if you want to, and dive into more advanced features and important third party packages as well. But with this video here, you will already get a solid foundation, a solid foundation, which you will always need as a React developer. We'll explore all the key concepts you must know, and we'll explore them by building a demo application so that by the end of this video, you'll be able to get started building your own basic React applications and you are ready to dive deeper into React with my course, or of course, also with our resources. Either way, for this video here, you need no prior React knowledge, basic JavaScript knowledge is enough and therefore, let's dive right in. Now to get started, let's start by diving into the most important question first. What exactly is React.js? Well, the official website tells us, React is a JavaScript library for building user interfaces. And that's a nice sentence, but what exactly does it mean? Well, obviously, it's a JavaScript library, so we will write JavaScript code, we use React in conjunction with our own JavaScript code, but it is a library that's there to help us build user interfaces. And I might add that it's there to help us build highly interactive user interfaces. You don't necessarily need React if you build a simple webpage on which not a lot of things are happening. But if you're building a more interactive website like the demo project we're about to build, then React.js can be a huge help vastly simplifying the code you have to write. And to show you what I mean, consider this very simple example here. I got this user card where I have this contact button and if I click this button, this modal overlay opens up and there I can enter some address and submit it. Now this is not super fancy, but we have a website with some interaction on it. We have a website where I can open this modal and enter data and submit it. Now on this demo website, nothing's happening to that submitted data, but we do have a website that does support some user interaction that must be interactive and reactive because we must React to button clicks and open this overlay. And even though that's a pretty simple example and a simple website here, the JavaScript code we could write to make this website work this way and to make the website behave that way when not using React.js could look like this. And while this is of course not too much code, it's quite a bit of code for this simple interaction and it's probably easy to imagine that if we had a more complex website with more user interactions on it, we would need to write a lot more code. And of course, therefore, we would introduce more potential error sources. Now when building the exact same application with React.js, The code suddenly looks like this, combined with this. And whilst this is still some code, it's a bit more readable and easier to manage. And as soon as you know React, which you will do by the end of the video. It's also much easier to read as you will see. Because even though you don't know React yet, you can clearly see that we seem to be writing some JavaScript code where we have some HTML code blended into that JavaScript code. And we then have clear instructions like SetShowModal, which seems to do something which in the end leads to that modal being shown conditionally. And again, I will teach you all that code and React syntax and all these React features step-by-step throughout this video. You don't need to understand them yet, but you can probably see that we have some clear instructions here and some clean code and most importantly, some HTML code blended into the JavaScript code. Which is a feature that's supported by React and by the React projects we'll be working in, as you will also learn in this video. In case of the raw Vanilla JavaScript code, we just had step-by-step instructions where we tell the browser step-by-step what should happen on the screen that we want to add an event listener, that we wanna create a new HTML element, how it should be configured, where it should be added and much more. We have step-by-step instructions. And indeed we call this approach of writing code the imperative approach where we have step-by-step instructions simply describing step-by-step what the browser should do. On the other hand, when using React.js, a major benefit of doing so is that we're able to write declarative code where we write the code for the UI that should be output on the screen and we blend some syntax like event listeners or dynamic values into the HTML code and combine it with extra React features where we can, for example, define different states and under which circumstances these different states should be active. And React.js will then generate the appropriate instructions for the browser under the hood. So that as a developer, we don't have to write these step-by-step instructions. And that is indeed one of the major benefits highlighted on the React.js website as well. The fact that you write declarative code when working with React. Now again, this is just a simple example with a lot of code we don't know yet, but that's one of the major advantages of using React. We often can write much simpler code, and therefore actually build way more powerful user interfaces. So let's get started with React then. And to get started, we first of all must create a React project. Now when working with Vanilla JavaScript, creating a project is as simple as creating a new folder and adding a bunch of HTML, JavaScript, and CSS files in there. Now when building a React web application, a React website, it's not that simple. Instead you need a project that performs various behind the scenes code transformations automatically. And you typically also want to have a nice developer experience where the React app you are working on is previewed and automatically updated whenever you change the React code. Now, the behind the scenes code transformations are needed because as I mentioned before already when building React apps, you typically blend HTML and JavaScript code in one at the same JavaScript file. Now technically this is not valid JavaScript code though, the browser would not be able to execute this code and we will of course learn why we're blending the code like this in just a second. But it is important to understand right now already that this code would not run like this in a browser. That's why it must be transformed, compiled, you could say, to some valid client site JavaScript code that's supported by the browser first. So that we as a developer have the convenience of mixing HTML and JavaScript code and as a output we still get code that's supported by the browser. And that's why we need a project set up that comes with some built-in tools that give us this life preview with the order reloading up on code changes and where we also get our code transformed under the hood, so that once we're done building our React app, we get a website that can be deployed on some hosting providers and that can then be visited and be viewed correctly by visitors from all over the world. So we need a project set up that supports these requirements. And a popular tool for creating such projects that come with all these features and tools that we need built in is Create React App. This is a tool which you can use to, well, as the names are just Create React Apps that give you this auto reloading and that support this HTML with JavaScript syntax. An alternative tool which you could use is Vite, which can also be used to create new React projects. And you can simply follow the instructions shared on these websites of Create React App or Vite to create valid new React projects. Now for both tools and also to successfully then run the projects created by those tools, you must have Node.js installed on your system. Now you don't need to be able to write Node.js code, you don't need to know Node.js, but Node.js is used under the hood by those tools that create the projects and then also by the projects and they're built in tools as well. So make sure you have Node.js installed on your system, you can typically download the latest version of Node.js Or use the latest LTS version, the latest long-term stability version. And once you got it installed, you can create those new projects with npx create React app to use that tool or by running npm create vite to use that Vite tool. And I'll do that, but you can use either of the two approaches. Now, once you run these commands, you are typically asked to choose a project name, and here, I'll just name it React crash course. But the name is up to you. And then in Vite's case, pick a template, where I'll pick React and then JavaScript. And this now creates a new project. Now once that was done, you can open that newly created project with an editor of your choice. In my case, I'm using Visual Studio Code. And you can start working on that code there. Now if you use the Vite, you also must open the terminal first and navigate into this folder. And for that here I'm using the built-in terminal in VS code, which is already navigated into that folder by default. And run npm install to install any extra third party packages that are needed to build and run and preview your React application. Once that's done, you can run npm start when using a project created with Create React App and npm run dev when using Vite which I do here. And then you can visit the website on this address, which should be output in the terminal to preview your React app. And the exact output on this screen here might change over time, but you now have a basic React project, which we'll now use to learn React. As a side note attached, you also find a link to a project snapshot which I prepared, which was created with help of Vite and which I also cleaned up a little bit so that we can all start with the same starting state. So feel free to also look into this starting snapshot and use that starting snapshot to follow along. So here I am now in my brand new project which I created using that starting snapshot, which was also attached to the last lecture so that you can simply download that starting snapshot which was created with help of Vite, and which I simply cleaned up a little bit so that we only have a few files in there. And this is now the starting snapshot will use to dive into React and learn about these React essentials. Now to briefly get you started with the project we have here, a project created with Vite in this case. In the end, what I do have here is an index HTML file, which isn't too important for us here because we won't add any code to that. Instead, we will work in the source folder where we have some .jsx files. And in the end these are JavaScript files that also support HTML code inside of them. This special syntax which I mentioned, which is not supported by browsers but which is transformed under the hood by the project setup we have here into code that is supported by browsers. This syntax of having HTML in JavaScript is called JSX, and that's why these files have these special JSX extensions. But again, this is not supported by the browser. This is transformed under the hood instead. What's also worth noting is that I have a CSS file here with some basic CSS styles and this file is also being imported here into a JavaScript file in the end. Normally this would also not work in the browser, but this is never feature supported by this project, which is then transformed under the hood and you can kind of see what it's being transformed to by opening up the developer tools in your browser for this starting snapshot website. And there in the head section, you for example see that a bunch of scripts and styles were injected. For example, the styles that were defined in this extra CSS file. So this project set up and some tools that were installed as part of this project setup simply detected this CSS import, and therefore, included this CSS code in the final website that's being loaded. You also see that a JavaScript file is being loaded here, which if you take a look at it upon loading this website in the end contains the transformed JavaScript code where you no longer see HTML code as part of the application, but where you instead have some raw optimized JavaScript code, which in the end is responsible for outputting on the screen what we see here. So that's what we got, that's what we'll start with. That's this special JSX syntax which will become important when working with React. And with all of that out of the way, let's now take a closer look at the code we have in these two JSX files, because there we have some strange code which clearly seems to be responsible for outputting Hello World, but it probably makes sense to understand how these different code pieces work together and what's happening here. So what's happening in these two JSX files? Sure, we have this HTML code in there which is called JSX as you learned. But what exactly is this code doing here? Well, let's start with main .jsx. So I can tell you that this is the main entry file of the entire application. The code in this file is executed first when this website is being loaded in the browser. But what's this code doing? Well, we're importing some things from React libraries. This is in the end the modern JavaScript import syntax, which is also supported by this React project we created here. And we are importing some features from the React library and from the ReactDOM library. Now these libraries are installed in this project with help of this package.json file. If you take a look at this package.json file under dependencies, you find React and ReactDOM. Now package.json is a file that's used by Node.js for managing the dependencies of your project, the third party packages you wanna use in your project, and it's also commonly used by front-end projects where you don't build Node.js applications for managing the packages of those projects as well. So therefore, this project which we have here, which I created with help of Vite, but it would be the same with Create React App, uses the package.json file to define external dependencies to define which third party packages will be used in your code. And here we're using React and ReactDOM, which are simply two separate libraries created by the same team. And these two libraries together form React, the React Library, you could say. It's simply a combination of two packages. Now in main JSX, it all starts with this ReactDOM thing because there, we call the createRoot method. This method takes a pointer at an element in our HTML code, and this is indeed a regular Vanilla JavaScript code here, document getElementById is not React specific. And what this code does is it reaches out to this element here which has the id root in this single HTML file that we have in this project. It's the only HTML file in the entire project. So this code here in main.jsx reaches out to that root to this div with id root. And then it calls the render method in the end on this object returned by createRoot it calls the Render method which is a method provided by React by that ReactDOM part of React to be precise. And we then do this, we then pass some JSX code to render. And in the end this simply tells React that inside this div with id root or in general, the element with id root, this React code should be rendered. So should be displayed on the screen. Now this strict mode thing here is a special feature offered by React, which is simply enabled some extra checks warning us of potentially suboptimal code we could be writing also in regards to future changes that might be added by React where it wants to warn us if we write slightly outdated code or anything like that. The more important part is this app thing here. Because this is actually also being imported. This import where we import App from ./App that in the end gives us an App thing, an App element as it seems, which is then rendered here with help of this JSX feature. So by using it like a HTML element in our JavaScript file. Now ./App simply refers to the App.jsx file. For JavaScript and JSX files, you can and should omit the file extension here in your import statements, and therefore this refers to App JSX. And in there, we are exporting a function called app. That function is a very simple function. All it does is it returns more JSX code, it returns the h1 HTML element with a text of Hello World inside of it. Now this is a so-called React component, and React is all about components. When you build React apps, you in the end build components and components are simply functions that Return JSX code. It's not entirely true, theoretically there are a few other things they could return as well. But typically the return JSX code. So functions that return JSX code are React components and React components can be used in other JSX code. That's why this app function as we just learned, which is imported in main JSX, can be used like a HTML element in this JSX code which is passed to render. Because render once in the end some HTML code, some JSX code to be precise that it should output on the screen and we can use our own component, the App component as part of that JSX code. Now our own component, the App component returns this h1 element, and therefore, ultimately, it's basically this h1 element which is passed to render between those StrictMode tags which we can ignore. And that's why we see Hello World on the screen here. The content of this App component, which we have here. And I am aware that these are a couple of new concepts, JSX components, definitely some new stuff here. But they are also amongst the most important concepts React has to offer, because React is all about you writing your own components, so your own functions that return HTML code in the end and using these different components for then composing a more complex user interface, because components are a key building block when working with React. Ultimately any website you think of can be split up into different building blocks that make up the website like a header at the top, a sidebar on the left and so on. And with React, you simply build these individual building blocks as functions that return JSX code. And by combining these building blocks and potentially nesting them into each other, you can build complex user interfaces in a granular, easy to manage way. Now it's not the only important feature added by React, but it's a key feature nonetheless. And therefore as an next step, we'll start building our first custom component together instead of just working with these predefined ones. So let's get started writing our first custom React code by building our first custom component. As mentioned components are these functions that return JSX code and as a React developer you'll write dozens and hundreds and thousands of those components to build up your React applications. Now we're about to build a Twitter like demo application where random people can post their stuff for the entire world to read it. Amazing. And along the way whilst building that application, that demo website will dive into many core React features and we'll get started now by building our first custom component. Now for this demo application which we're about to build, there are actually multiple possible components we could identify. We could, for example, build this button as a separate component or this list of posts of tweets, if you want to call it like this or the individual tweets. And indeed that is how you should think of components and React applications. We have all these building blocks and we then build the overall UI by combining them. Now, of course, you don't have to put every single character into its own component, but it makes sense to group related functionalities together into different building blocks. And here we could, for example, start by taking a closer look at the individual posts and the first custom component which I wanna build together with you therefore is a component for such a single post. And later, we'll be able to then output multiple posts based on that custom component. Now therefore, back in this project which I gave you, I'll go through that source folder and in there add a new folder called components. Now this name is up to you, you don't have to name this folder components, you don't even have to create a folder in the first place, but it makes sense to group your component files together into such a folder. Now this App JSX file, which technically also contains a component is not part of that folder because that will soon be our root component. And I'll get back to the concept of our root component later. So for the moment, let's go to components, and in there, I'll add a new file called Post.jsx. The name is of course up to you, but post makes sense since we're about to add the code that defines a single post in there. The markup that defines a single post, for example, and .jsx is required because we plan on writing sub JSX code in there. If we had just .js, that would work in projects created with Create React App. But Vite projects actually want .jsx to support JSX code in JavaScript files. And now as a next step we have to create a function because React components are just functions. It's as simple as that regular JavaScript functions with one special gotcha though, the name of your functions should start with an uppercase character. And, of course, the name also should describe what this component will be about. So here, I plan on defining the markup that defines an individual post in that grid of posts and therefore all named a function post like this. And the uppercase starting character is important. It's not required technically in here, but it is a recommendation and it will be required later. Now this function should be exported so that it can be used in other code files as well. And for that you can use the standard modern JavaScript export syntax where you either export it like this by adding the export keyword in front of the function or as a file default. And the only difference is then regarding how you import that function in another file. So here I export it as a default. And now in that function, as mentioned before, we should return some JSX code, because that is what turns a regular function into a React component. It's really only the fact that you start with an upper case character and even more important that you returns some JSX code. Now for a single post to get started here, we could return a div and then in there maybe a paragraph where we output the name of the author of the post. And below that another paragraph with the post body like React.js is awesome. Now after hitting my auto format shortcut here in VS code, I get this function and that is now indeed our first custom React component. But, of course, if you just add this file like this and save all changes, nothing changes on the screen. And by the way, you must make sure to keep that npm run dev process here up and running in case of a Create React App project, it was npm start, with Vite, its npm run dev, and this starts a development server which watches your code files, serves your website on the address that's being output here in the terminal. In my case, localhost 5173, so that you can preview your React website there as you are building it. And it will automatically reload the website here and update the website, and update what you see on the screen as you make and save changes to your code. So that's why this process must keep up and running. But with that, we still don't see our post content here, we still see Hello World. The reason for that is that I created this component, this post component in a separate file, but I'm not using it anywhere. It's the same as with a regular JavaScript function. If I add a function called add, where I do something, even if I export that function, it's still not getting used anywhere. Instead, exporting is just the first step to make it usable outside of this file. But we then have to use the function outside of this file and it's the same with this component function. Now the place where we wanna use our component functions is inside of JSX code of other components. So you build your complex user interfaces by combining components with each other and nesting components into each other. Now at the moment we have two places where we do have some JSX code in use. That's the main JSX file where we pass some JSX code to render and App JSX where I return Hello World. Now in both places we could output our post component, but typically when building React user interfaces, you have one root component. So one single component that's being output in main JSX and in this case, that would be the App component here. And then inside of that component, inside of the App component in this case and any components used by that component, you use your other components. So the post component should be used in the JSX code of the App component. So there instead of outputting Hello World, we could output post like this. Now in order to use it, we have to import that component function though, and we do that by using the import keyword and then post from ./components/Post. And the file extension should be omitted as mentioned, but you have to specify the full relative path from App JSX to that Post JSX file. So with that we're importing this post component function and even though it's a function, we're not using it like you would normally use functions by executing it, but instead, we're using it like an HTML element in this JSX code that's returned by App. In this case, it's the only element that's returned and that's the special thing about your component functions. They are standard JavaScript functions, but you can use them in JSX code and behind the scenes React will basically execute your component functions for you. Take a look at the HTML, the JSX code to be precise that's returned by them, and then build the overall user interface and render it to the screen, that's what React is doing for you. So React is then generating the browser instructions that are needed to bring your HTML code to life in the browser. And what's really important is that in the place where you use a component function in JSX code like we're doing it here with Post or in main JSX with App, your component functions must start with an uppercase character. It's optional in the file where you define them, but there you typically also start their names with an uppercase character, but it's absolutely required in the places where you use your components. So in App JSX, where I import post from the Post JSX file, this name here Post must start with an uppercase character. It should not start with a lowercase character because in the JSX code, you add to your components. Elements that start with a lowercase character are considered to be default elements. So React will try to find a default HTML element with that name, which it would not find in case of Post and elements starting with a uppercase character are considered to be custom components. And in that case, React will go ahead and execute your custom component function as mentioned before. But that's why default elements like div are written like this and do not start with an uppercase character, but your own components must start with an uppercase character when using them in JSX. And that's really an important rule to memorize. But with all of that out of the way, if we save everything, we get this content on the screen, and this is now the content we defined in our own post component here. So even though it's not super fancy and definitely not interactive in any way, it is our first custom component defined and used in our React project. So we got our first custom component here, and it won't be the last component we'll work on. At the moment, it doesn't have any fancy styling, but we'll add some styling soon. But I'd like to make it a bit more dynamic. And for that I'll start by going to Post.jsx, and then there outside of the component function though it doesn't really matter, I'll add a new constant called names which holds an array of two possible names, Maximilian and Manuel. And I wanna output one of the two names whenever this component is rendered. So basically whenever I reload the page and idea for cause React to re-render the screen, I wanna make sure that React picks one of the two names and outputs it on the screen, so that it's not always Maximilian, but we get some randomness on this website. Now how could we make this work? Well, in order to make this work, we first of all must add some logic to this component function to pick a random name. So we could add a constant called chosenName. And then here, I want to call Math random. This built-in random method that's supported by browsers out of the way. So this is absolutely not React code, this is all built-in instead. And if what I get here is greater than 0.5, I wanna pick the first name. So names zero, otherwise names one. So with that I have a 50/50 chance of picking Maximilian or Manuel. Now this as mentioned here, is standard JavaScript code and it's important to understand that even though this will be treated as a component by React, it in the end still is a function that will be executed by React. And therefore, in this component function you can in the end run any JavaScript code you want in that function. It's just important that in the end your function returns some JSX code. So here, I'm picking a random name and I now wanna output that name here instead of always outputting Maximilian. But how do we get this chosen name from here to here? Well, for that, we'll use a special syntax that's supported by JSX and React. Instead of hard coding the value here between these paragraph tags as we're currently doing it with Maximilian, we add opening and closing curly braces, single opening and single closing curly braces. And between those curly braces, you can put any JavaScript expression of your choice, like for example, two plus two. If you do that and you save that, you'll see that now we get four as a output here. We get four here, because when you use this special curly brace syntax in your JSX code, React will go ahead and take whatever is written inside of those curly braces and execute it and then output the result of that expression that was executed. So in this case, we have two plus two, hence the result four is output on the screen. And we can, of course, not just perform mathematical calculations here, but instead, we can also reference variables or constants. So here, I can output chosen name and instead of outputting the text chosen name now as it would do without the curly braces. Here, we get the text chosen name, with those curly braces, it will instead look into that constant or variable and output the value that's stored in there. So now we'll get either Maximilian or Manuel. Right now it's Maximilian for me here, but as I reload this page, you see that it switches between these two names here, and it switches after every reload because a reload technically restarts the React application and causes all React components to be re-rendered on the screen. And even though this randomness is not a feature we'll need in a finished application, it is super important to understand how you can output dynamic values in your React applications. Because even though you might not need random values too often, you do very often need the results of calculations of data fetched from some backend API, something will also do later in this course, or all kinds of other dynamic values. So this is an important piece of syntax you must keep in mind. Amazing. We get a component with some dynamic value being output as part of it. And therefore, as we reload this App, the names are changing here. As mentioned before, it's probably not a feature we'll need all the time, but it's a huge step forward. However, at the moment, we're using this Post component just once here in the App component and that is indeed often the case. You define a component and in the entire application you use it only once. For example, if you define a separate component for the MainHeader of the application, the main navigation bar of your website, let's say, you typically only have one main navigation bar on the entire website and you nonetheless might wanna put that into its own component so that all the navigation logic is in one and the same place. But whilst this is a common use case, it's also very common that you wanna reuse a component and the Post component is a perfect example. Why just have one post, we might have multiple posts on our website, not just one post? And indeed later, we will have multiple post, users will be able to create multiple posts and we wanna output a grid filled with all those posts. So how can we output multiple posts based on that one component? Well, that's also quite straightforward. In this App component here, let's say, we output a main element and that's a standard HTML element supported by the browser out of the box. And you can tell that it's a standard HTML element by the fact that we start with a lowercase character and that we're not importing it from anywhere because React supports all these standard HTML elements that are supported by browsers out of the box. So I output this main element here, and then inside this main element, I output my Post like before. But I don't just do this once, but instead twice or three times or four times, how often you want. If you do that, you see a bunch of posts here, and if you reload you see that they all can have different names. Sometimes you have the same name in all those posts, but you have a high chance of having some variation. We do have some Maximilians, and some Manuels here in my case. This also shows us one important feature of components even though we use the same component function multiple times, it's in the end executed multiple times by React, so it's not just executed once and the result is then reused, but instead it is executed multiple times once per usage so to say. That's why we have different names here, because the component function was executed multiple times by React and that's in the end how a component can be reused. You can simply use it multiple times in your JSX code. The same component used multiple times. Now there are a couple of important aspects related to reusing components and I wanna start with one important restriction that's in the end enforced by React. When you have multiple elements side by side as it's the case here with multiple posts, but the same would be true if we had multiple built-in components, you must make sure that they're wrapped by another component. Put in other words, in places where you use JSX code, like in the return statement here, you're only allowed to return one single element and that element then in turn might include multiple sibling elements, but we would not be allowed to return this JSX code. As you see, I'm already getting an error here. I'm getting an error because in places where you use JSX, you must have one root JSX element like this main element here. And then in there, you can have as many sibling elements as you'd like to have, but you must have one root element. So that's an important restriction to keep in mind. Now if there is no fitting HTM element that you wanna use, you can also use empty opening and closing tags and this syntax will actually be supported by React, but you must have won wrapping root element nonetheless. In this case, I'll use the main element though because semantically it makes sense to wrap the main page content into that element. And since we're already talking about JSX and an important restriction and force by React, there is another important rule you must follow. If you have elements that have no content between their opening and closing tags, as it's the case for Post. You may write them as such, so opening and closing tag without content between, but you can also write it as a self-closing tag. You however are not allowed to write it as a void tag. You see I'm getting an error here. So you either must add a closing tag or write it as a self-closing tag. And that's true for all elements you're using in your JSX code, no matter if we're talking about custom components or built-in components. If they have no content between the opening and closing tags, they must be self-closing or you must have opening and closing tags. And if you have sibling elements, you must wrap them with a root element because you can only return a single element in your component functions. So these are some important things you should keep in mind when working with components, including scenarios where you are reusing your own components. Now when reusing components, so using one and the same component multiple times as we're doing it with Post, there's also another important React feature you must know to make those reused components more useful because at the moment the component we have here, the Post component is of course still fairly static. Sure it has this random name that's being output, but in the end here, we also just have a static choice between two names. This component isn't really useful yet. Later when we're able to create posts and store them in some database and fetch them from there, we wanna be able to reuse that component with different names and different text values that are coming from a database, for example, so that are not hard coded into the code. Well, we don't have the database part yet, we don't have any data fetching yet, but we can still start preparing this component to be more useful by adding a feature called props to it. For that, I'll first of all get rid of that randomness code because I don't need it anymore. And instead, I wanna make sure that both the name and the text here can actually be configured from inside the place where this component is being used. So from inside the App component in this case here. So it would be great if we could use the Post component here or anywhere else in the App, doesn't matter. And we could pass different values to that component just as you can pass different arguments to one and the same function if you are calling a function in your code. If you have a add function that takes two numbers and returns the sum of those two numbers, then in JavaScript, you can call this function with different arguments, right? That's how JavaScript works. Now, it would be nice if we could do the same thing with components and pass different values to one and the same component. And that's where this props feature comes into play. React allows you to add your own attributes called props to your components. For example, here a author prop, which could be Maximilian in my case here, and then maybe a text or a body prop, which could be React.js is awesome. And then the second time we use the Post, we could set a different author like Manuel and give it a body like check out the full course. So now I'm using the same post component function here with different values set for author and body. This alone won't do the trick though if we save all files, we now got no content on the screen, because whilst we're passing data to the post component with our custom attributes here, so with that feature called props. We're not using these values inside of the post component. How would React know where the author or body information should be output if it should be output at all? Well, it doesn't. That's why we have to tell React how to treat those props. But how do we tell React? Well again, if you have a regular function like the add function, you receive parameters and you can work with these parameters then. A and B, in this simple example. It's the same with custom components. There you receive a parameter, a single parameter though, and the value for this parameter will be passed two this function by React, which should make sense because I mentioned before already that React will be executing your component functions. So here, we can receive this parameter and I'll name it props though the name is up to you because it will be an object using this concept called props in the React world. So this is simply a name made of by the React team that we get this props, this property collection object here as an argument in this function. So this will always be an object what we get here, and this special thing about this object is that it will have all these custom attributes that were set on the component as property names, so as keys that we can access. So here, since I'm setting author and body on my custom component, I can access props.author and props.body on this props object that's passed into this component function automatically by React. So therefore here in the place where I wanna output the author name, I can output props author. And here where I wanna output the text, I can output props.body and remove this code here. And with this simple yet important change. And by using this super important feature called props, we can save all our code files and we got our two components back, but now this time configured with different values. So it's the same component function, it's a single component function used with different configurations, with different values for these props. And thanks to us using this props feature inside of the component function, we dare for do see this different content on the screen. And that's how you make components reusable. Now, as mentioned before, not all components must be reusable and some components might not need any props at all. But that's up to you as a developer. You can build your own components and if you have a certain component that should be used in different places with different values, this props feature is your friend. So we got a reusable component, but one thing's missing, I guess a lot of things are still missing here, but one thing that's missing on our component here is some styling. We have some white text and right now, it's not even easy to tell where one component ends and the next one begins. I mean we know because we created it, this name is the start of the second time, we're using this component of the second component instance, therefore, but it's not obvious to see. And in general, typically, you want to style your components and not just add the markup. Just as for any website, you don't just want the HTML code, you instead also want styling. Now for React there is an endless amount of styling solutions, and I talk more about different approaches for styling components in my complete guide course you can, for example, add inline styles by adding the style attribute to your elements. Now, here the important thing to understand though is that you should not add your styles like this. So some strings, some text that defines your styles, but that instead you should add a dynamic value and then pass a JavaScript object as a value. So this is not some special double curly braces syntax. Instead it's still the same single curly braces syntax we used down there, but with the object passed as a value to the style prop. And then in that object you set your styles like for example, color red and text align left if you would want to make it really ugly. With that code, we would get that styling and yeah, but that's one way of styling. But just as with Vanilla HTML and CSS, typically you don't want to use inline styles. Instead it's considered better practice to put your CSS code into CSS files. And indeed this project has one CSS file with some styles being predefined. And what you could do is add a class to your div and then, for example, give this a class of post to then set the appropriate styles in index CSS. But wait a second, did I just write class name here instead of class? Yes, I did. The JSX code you write might look like HTML code but it actually isn't HTML code. Instead it is a JavaScript version of HTML and some HTML attributes have different names here. Now to be honest, not too many, so nothing to worry about. But class is one of the most important attributes that has a different name when writing JSX code. Instead of assigning CSS classes with the class attribute, you instead use class name. Now there are some technical reasons for that, that the JavaScript elements that are created under the hood have class name as a property name for setting CSS classes, but those details aren't too important to keep in mind. Instead, what is important to keep in mind is that CSS class names are added to elements with the class name prop and not with just class, but with that name being used, you can then set any class name of your choice. And if we use post here, we could for example add a post class here in the index CSS file to give this a background color of light blue. And if we do that, we will see that background color here. Obviously still ugly, but that's another approach for assigning styles. We can set up global CSS classes here and assign their class names like this, but besides the fact that this is rather ugly, which of course is a problem that could be solved, there is another problem related to this approach. When using global class names, you could have name clashes in bigger, more complex projects. You could have multiple components that use the post class name internally, for example, and your globally defined CSS classes could then clash with each other. Put in our words, you might prefer to scope CSS styles to your different components. So that styles applied to the post component really only affect that component and can't possibly clash with other styles in other components. And React projects created with Create React App or Vite also support a solution for that problem. Instead of defining the Post style like this, you can add a dedicated CSS file, which I'll name Post.module.css which should typically be located next to the JSX file though it's not technically required, it's just a convention. What is technically required though is that the file name is Post.module and then .css as the extension. But the .module part is important. This tells Vite or Create React App that you wanna use a feature called CSS modules here. Now CSS modules is in the end an approach you could say, an approach that's implemented by projects created with Vite or Create React App where the class names you set in your CSS files and which you then use in your HTML or JSX code are under the hood transformed to guaranteed unique class names, so that name clashes are avoided. And by using .module in the CSS file name, you tell Vite or Create React App that you wanna use this CSS modules feature. Now for this Post component, I prepared some styles which you'll find attached and I just pasted them into this Post module.css file, these attached styles, and we can now use them by going back to Post.jsx. And in there, we now first of all have to import this CSS file. Now in main.jsx as CSS file is imported by simply using the import keyword and then the path to the CSS file name. When using CSS modules, this syntax must change a little bit. We do still import from that path. So in this case from Post.module.css, which is the relative path to that CSS file seen from that Post.jsx file. But instead of just importing the file like this, we import classes or styles, the name is up to you, from that file. So you must use this import syntax and this under the hood will then kick off that CSS class name transformation process that's supported by the project we have here. And the classes thing we get here is in the end an object where any class names used by you in the CSS file will be available as property names. And then the values for these property names will be the transformed unique class names. So we can use this classes object to set the class name on this div to classes.post, .post because in Post.module.css I have a Post CSS class selector. And as I just said, those classes which are defined with class selectors in the CSS file will be picked up by some behind the scenes process that's part of the project and will be converted to unique class names. And the unique class name is then yielded as a value for this Post property on the class object, which is imported from the CSS file. So we get some behind the scenes transformation magic going on here. And we can then also add a classroom here to the author, classes.author in this case because in my Post.module.css file, I also have an author class. I also have a text class, and this text class can the author be assigned down here? And please note that I'm always using this dynamic expression syntax with the curly braces to refer to the values stored under these properties on this class's object. And with that done, we now got this style, still not the final look I wanna have, but a great step closer to the intended final result. And if you now inspect this in the developer tools, you will see that there we have these CSS class names being assigned and these are clearly not the class names to find in my CSS file. Instead these are the transformed class names because as I mentioned, that's what is CSS module's feature does under the hood. And that's there for another possible approach you can use for styling your components. And it is the approach I'll use in this course here. But as mentioned in my complete guide course, I also show alternatives to that. Now we're making good progress here. We got our own custom reusable component with our CSS modules based styles applied to it. Before we dive into more important React features, let's practice what we learned. And for that I want you to build another new component PostsList component, which in the end should render a list, an unordered list, to be precise, that includes these two Posts and you should also edit the Post component to use a li instead of a div. That however, is a very simple change applied like this. The more important part is that you build that custom PostsList component, which uses the unordered list to output these two posts. And you should then use the PostsList component in the App component instead of these two Posts here. So try doing this on your own first. Here's a short pause for you to pause the video, thereafter we'll implement it together. So did you succeed? Let's implement it together. For that here in my components folder, I'll add another new file, because whilst not technically required, it is considered a good practice to put different components into different files. And I'll name this file PostsList.jsx since I wanna have a component named PostsList in there. Again, the file names just like the component names are up to you, but you should try to choose names that describe the purpose of the component. And you should use this notation where also in the file name you start with an uppercase character, and if you have a name that consists of multiple words as it's the case here, you should actually have a single word where every subword so to say, starts with another capital character like the L in list here. So that's the PostsList component. And here, I'll then add a function called PostsList because you learned that components are in the end functions and I'll export it as a default here. And then there we wanna return some JSX code. And the JSX code I do wanna return here is an unordered list. Now in that list I wanna output my posts here, which I already converted to list items so that we have semantically correct code. So therefore, we should grab these two posts from App JSX, and cut them there and get rid of that import since we don't need the Post component in the App component anymore. And instead go to PostsList and paste the two Post components in there. Now in order to use the Post component in this file though, we have to import it. So we have to import post from ./Post, the relative path to this Post component file seen from the PostsList component file. With that we have this separate list component here, but now we have to output this list component in the App component. And doing that is rather simply as well. First, we have to import it, so import PostsList from ./components PostsList. Here, we need the components part as part of the overall path because App is not in the components folder yet. So we have to first go into that folder before we can then target the PostsList component file. And here, we must start with an uppercase character as you learned. But then we can use PostsLists like this in our JSX code. With that saved, we have a list as you can tell by these bullet points here. But, of course, it's not really the look I'd like to have. However, this is the solution to the exercise I gave you. I wanna polish this solution though by also adding a PostsList.module.css file, and attached you find some styles which should be pasted into that PostsList.module.css file. And with those styles added here, and this Posts class being defined here, we can and should then also import classes from ./PostsList.module.css and apply that class here as a class name, that posts class as a class name to the unordered list. And with that, this starts to look nicer here, still not the final look I'd like to have, but we're taking some steps in the right direction. I now also wanna go to index CSS and get rid of this text align center style here in the body selector. With that, I make sure that the text is left aligned, which I think looks a bit nicer. And with that, we now don't just have a nicer look, but even more importantly, we now have another custom component and we can see how these different components work together. We're using the Post component multiple times, so with multiple instances as it's called, with different configurations with help of our props here inside the PostsList component. And we're then using the PostsList component in the App component, which in turn is used in main JSX to be output there. And that's how you build React applications and how you build user interfaces by composing them from different components. So by combining these different building blocks, these different components to come up with the final intended user interface. Though this of course here is not the final intended user interface. Instead we're just getting started and we're now ready to dive into another super important and for us brand new React feature. At this point, we already learned a lot about some important React features, but we're not done yet. Instead, it's now time to dive deeper into React and learn about another super important React concept may be the most important React concept after components and props and that would be state. Now what's state about? Well, let's say that in our component, we now wanna add a new Post component which simply displays a form where we can enter the text and the author name of a new post that should be added. And ultimately, in the application, the website we're building, we wanna be able to bring up that modal overlay.forum, which does allow us to add new posts. Now at the moment, we're not there yet. Instead we'll just render such a form and as we type into this textarea or this input, I wanna update the text that's shown in my first post here. As a temporary step into the right direction before we then later can really use that form to add new posts to this list of posts. Now for that attached, you find a link to this NewPost.jsx file and the NewPost.module.css file and you should add both files into your components folder. And this NewPost component, which basically looks like the other components we built thus far. It's a function that returns some JSX code, in this case, some form markup, but only using standard HTML elements. This component should now be used next to our list of posts here. So here, maybe above that list, I wanna use this NewPost component. But for that we gotta do two things. We have to import NewPost from ./NewPost so that we make this component available in that file. And since you learned that sibling elements are not allowed and at the moment NewPost would be a sibling to the unordered list, we have to add this empty element, this fragment as it's called as a wrapper around NewPost and unordered list so that we fulfill that requirement React has that in our JSX code in the place where we return or store the JSX code, we have only one root element. By the way, as a side note, inside of NewPost, you will see that on the label, I have this htmlFor attribute, and here, we have a similar case to className. It would normally be the for attribute, but this is not allowed in JSX code and therefore, here it's htmlFor. And the good news are that with className and htmlFor, you now basically know all important deviations from the standard attribute names that you typically use all the time. But with that, we got this new post component output there, and if you save all files, you should see something like this on the screen. This form above this list of posts. And my goal now is that as I type something here, I update this text down there. So in the end, this text should go down there and if I type a name here, that name should in the end go down there. And at the moment, that's of course not happening, but that's where this new state concept and feature can help us. So what's the idea behind state? Well, the idea is in the end that the websites you are building typically have different states in which they can be. If you have a dynamic website, so a website where things change after it was loaded as it's the case here where we want to change some text after it has been first rendered, if you have a website like this, then your website in the end has different states. This text here is one state, and if I enter another text here, and this text down there is updated, that's a different state in which our application is in the end. And React allows you to manage such different states so that it then takes care of updating the user interface as your states change. So in order to use this state feature to update this text down here, as we type something up here, we have to do two main things. We have to register such as state, and we have to set up an event listener that tells React whenever we type here, so that we tell React when the state should be updated and let's start with the event listener first. For that, we got this NewPost component here and then this NewPost component, we for example wanna listen to changes to this textarea. So we wanna listen to keystrokes in that textarea. Now in standard Vanilla JavaScript, we would try to reach out to this textarea with query selector, for example, and then we could call addEventListener to add an EventListener to this element. For example, the key down eventListener or the change eventListener, which will basically be triggered whenever the value entered into this textarea changes, including cases where we paste a new value into this textarea. So we might wanna listen to change and then trigger some function as this change event occurs, that's how we would handle it in Vanilla JavaScript. However, this is also using the imperative approach, we're telling the browser that we wanna get hold of the textarea and add an event listener and what should happen then. With React, we use a declarative approach instead as you learned, and therefore, with React, if you wanna add an eventListener to this textarea, you do that by adding a special prop, a prop that starts with on and then the name of the event to which you wanna listen. For example, onKeyDown, the important thing to note though is that you do have this camel case notation where you start with a lowercase character for the on and then the words thereafter start with uppercase characters and for the change event, it's therefore onChange. So you add this prop to the textarea here, for example, to listen to the change event. Now you also must know React know what code should be executed when that change event occurs. And for that, we can add a new function inside of this component function. And yes, you can have functions inside of functions that's not a React feature, that's a standard JavaScript feature instead, and this function could be called changeBodyHandler. The name of the function is up to you, but I prefer to have functions that end with handler if I plan to assign these functions to eventListeners. But that's not required technically, this function name is entirely up to you. However, now for onChange, you set this equal to a dynamic value and the dynamic value you wanna use here is your function. However, you don't execute the function so you don't add parenthesis here instead you just use the function name because in JavaScript, again, standard JavaScript, not React specific. Functions are totally normal values like strings or numbers or objects. Indeed functions under the hood are objects and therefore, you can pass functions to props just as you can pass numbers or text to props. So here, we're passing the changeBodyHandler function as a value to the onChange prop and under the hood, React will set up an eventListener for the textarea and set this function, the changeBodyHandler function as a target for the eventListener. So to be executed when that change event occurs and inside of that function, we can therefore now do whatever we wanna do. We'll automatically get an event object as a argument, as a parameter. And that also would be the case in Vanilla JavaScript when using addEventListener. They're the function which we set as a second argument also automatically gets an event argument by the browser. And the same is true here when using React. And that event parameter simply holds some useful information about the event that occurred, including the event target, which in this case is the textarea, since that was the target of the change event if it occurs here. And then there, we could get the value property and then, for example, log this to the console for the moment. Now this is Vanilla JavaScript code here, we get access to the target of the event and the target is the textarea element and that turns out to have a value property which holds the value entered by the user. So with this code, we're not doing anything with state yet. We'll get to that later, but we are setting up an eventListener and we're then logging the value entered into the textarea by the user who's on the website. Therefore, if you save save everything and you open the Developer tools and go to the console there and reload the site, if you enter something here, you see that for every keystroke, the current value is being logged here into the console. Now if I cut this and reload and paste it in, it's all the logged here because as I said, the change event is all the triggered if you pace something into this input area. So that's how you can set up eventListeners, and whilst this is not directly related to this state concept, it's still kind of an important prerequisite because whilst you can useState without events, you very often want to change to a different state upon the occurrence of a certain event, be that a value entered into an input or a button being pressed. Typically you wanna change something on the screen after a certain event occurred. And that's why it's important to understand how you can set up eventListeners. And this is how you can do it with React, you define your function, then this special on prop, and then you link your event listener to the function that should be executed by passing the function as a value to the event listening prop. And you then get this event object automatically passed into this event listening function by React. Okay, so now we know how we can set up eventListeners. Let's now dive into this state concept, and to get started, I simply wanna output the text that's input into this textarea in a new paragraph below this input in the end. We'll soon also make sure that it ends up in the post component, but for the moment, let's just output it there. To achieve this, we need to store the value somewhere and then reference that somewhere down there. And the first thing you might think about could be a variable. We could add a variable enteredBody which maybe is an empty string initially, and then here instead of console logging the entered value, we could store it as a value in enteredBody like this. So we update the variable whenever this function is executed, which happens on every keystroke as we saw. And then we could use this enteredBody variable down there in this paragraph. So here, we can use our single curly braces and output enteredBody. So this variable is updated here, and is then output down there. It should work, right? Well, if you save that and you type something here, nothing happens. It should be output down there, because that's where I added the paragraph. And indeed if you inspect this here, you will see that below this textarea here is an empty paragraph, but it is indeed that, empty. What I type here is not being output in that paragraph. Now is that the case? Well, because there is something very important to understand, React executes your component functions like NewPost and it then takes the JSX code returned by those functions. So the current snapshot of the HTML content, that should be output on the screen and it does render it to the screen. But if they are after in your component function, you change some variable value that's being used in your JSX code, that won't be picked up by React, because this JSX code is only taken once as a snapshot when this component function is executed for the first time. Indeed, if that component function would be executed by a React, again, it would also consider any updates to that snapshot and update the rendered user interface. But React does by default, not randomly execute NewPost again. And it does not execute NewPost or any other component function again, just because you changed some variable or just because you have some event listener in there. This is ignored by React. Of course, it adds the event listener and this function executes, but it does not care about whether this would theoretically change your JSX code. Instead, you have to basically create this variable in a special way using a special React feature to let React know about any changes that should cause a UI update. And for that, you have to import something from React, so from the React library, not from ReactDOM, but from just React, and that something is a function called useState. Now this is a so-called React Hook. React has multiple built-in functions that all start with use as you can see here with my auto completion and these functions whilst technically being standard JavaScript functions are called React Hooks. So functions in React that start with use are considered React Hooks. The special thing about these hook functions is that you must execute them inside of component functions. You can't execute them in regular JavaScript functions. You can but you'll get a warning or an error, but you must execute them in React component functions instead. And then those hook functions typically change something about that component or regarding how React behaves with that component. In case of useState, when you execute that inside of a component function, you register a new state slice as you could say, a new state value that belongs to this component. In a state value can be anything, it can be an object, a number, an array, a string, whatever you want. Here, if you wanna store the entered text, we could register a string as a state slice for this component. You set a default value for that state variable if you want to call it like this, by passing your initial value as an argument to useState, for example, an empty string just as I did it down there. But again, that could be anything, it can be undefined, it can be a number, it could be an object, but here it's a string. UseState then returns something, it returns an array and I'll store that array in a constant, state data is a name we could use here. Now this state data array has always exactly two elements, never more, never less, and the first element of state data is always the current state value. So initially that empty string, but that value can change as you will soon see, because that second element in that state data array is a state updating function. A function which you can execute to assign a new value to your state, because that state value is stored somewhere in memory by React. You set an initial value and you can then call this function, which is returned by useState as a second element in this state data array to update that value. Now the special thing about that is that if you call that state updating function, you don't just store a new value somewhere in memory. But React will also re-execute that function in which this state was registered. So it will call this component function again, just as it did initially when it rendered that component for the first time. And since it calls that component function again, you get the current state value, so the value which you just set with help of that state updating function as the first element here, and you get the latest JSX snapshot, and if that deviates from the previously rendered JSX snapshot, React will update the parts in the UI that need updating, and that's by the way, all is important. React will basically make a comparison between the different snapshots behind the scenes and only update the parts in the UI that must be updated. So that you don't unnecessarily update the DOM, which is quite performance intensive. So that's what you get back here. Now it's quite common to use array destructuring here, which is a default modern JavaScript feature to store the current value in a constant and the updating function. And typically, you should pick names here that describe your state, like for example the enteredBody and then the updating function could be called setEnteredBody. It's kind of a convention to name this state updating function set, and then you basically repeat your state name just formatted as camel case. Now I'll remove that variable here, because we have a name clash otherwise. And with that, we registered this state. Now to update that state, you don't try to assign a new value, that's why I also use the const here for these two values. Because instead you have to call this state updating function, setEnteredBody like this, and pass your new value as a value for this argument to setEnteredBody, then behind the scenes the new state value is stored and this component function is executed again and enteredBody will then hold that new value. That's why it may be a constant because it's always a brand new constant, because it's always a brand new function execution in the end when you update the state. So now we can use this enteredBody state here in this paragraph to output the useState value. But this time, because we're using this state feature provided by React with help of the useState hook, this will all work. And if I now save everything again, you will see that as I type something here, it updates down there below the text input. So this works now and with every keystroke this gets updated as you can see. Now that's React's state feature inaction. So that's how we can use state. And the special thing really is that when you update your state to component function gets executed again and therefore the latest JSX snapshot gets used by React, gets compared to the previous snapshot, and the UI is updated where needed. Now here, however, the goal was to basically get this text into this first post component, and of course, that's not happening right now. One problem we're facing here is that this state is inside the NewPost component. That's great, but we don't need it there. Instead we need it in the PostsList component so that we can set this entered text as a value for this body. Now how do we get the state from NewPost to PostsList? Well, an obvious solution would be to import useState from React in the PostsList component and register the state there. We could have the enteredBody here with help of useState and this should use object destructuring here to get the enteredBody and the setEnteredBody state updating function. Now we have the state in the component where we need it and we could set this body to the value that's currently stored in enteredBody, so that our current state value is output down there. That's amazing and great, and theoretically, that's a good approach, but now we have the state in the right place, but the event is in a different component. So how can we solve this puzzle? We either have the state or the event in the wrong component. Well, what we have to do here and what we already started doing is something that's called lifting the state up. If you have state that's manipulated in component A, but needed in component B, you should lift this state up to a component that has access to both components that need the state. So in this case, it's the PostsList component that needs the state to pass it to post as a value for the body prop. And it's also the PostsList component that has access to the NewPost component, which is the place where the state should be manipulated. Now what we can do in this case is we can get rid of the state here in NewPost and get rid of the event handler function and the useState import as well. And we could now simply use this props feature. So this props object which we get by React automatically to set this onChange eventListener prop equal to, for example, props.onBodyChange. Now this prop name is up to you, because you can set any props you want on your own components. With that prop being set like this on the onChange prop of textarea, we can go to PostsList and on NewPost, we can now add the onBodyChange prop here to the NewPost component. And as a value we can now again pass in a function that should be called when the textarea changes, so when the change event occurs on the textarea. In this case, for example, the bodyChangeHandler where we automatically get the event object as before and where we then call setEnteredBody equal to event.target.value and it's then the bodyChangeHandler function, which is passed as a value to onBodyChange to this prop. Now this might be confusing at first, but what I'm doing here is I'm passing this bodyChangeHandler function to onBodyChange. So we're not executing it here, we have no parentheses, instead I'm using this function bodyChangeHandler as a value that's passed to the onBodyChange prop. Now in the NewPost component, I'm then in the end forwarding that value that's received on the onBodyChange prop as a value to the onChange prop of textarea. So we simply pass that function, that bodyChangeHandler function through the NewPost component with help of the onBodyChange prop to the textarea component. And this should all be quite a bit less confusing if you keep in mind that functions can be used just like any other kind of value in JavaScript. So therefore in the end here, we wire up this bodyChangeHandler function, cutest change event on textarea, that's why we also still get this event object. And with that we can now update the state in the component where we need it whilst still setting the listener in the component where the event occurs. And, of course, we can also do that with the author input. There we can add the default onChange prop to add a change event listener to that input as well. And for example, expect to get a function value on the onAuthorChange prop. Again, this prop name is up to you because it's your component, but with this prop chosen here inside of NewPost, we now have to use the same prop name here on the NewPost component in PostsList and then copy that bodyChangeHandler function and name this copy AuthorChangeHandler, for example, to then pass this AuthorChangeHandler function as a value to the onAuthorChange prop. And then again, that's picked up, and used as a value for the onChange prop inside off that NewPost component. Now, we just need to register a second state slice for that author name and that is something you can do. You are not limited to one single state per component, instead you can have as many state values as you need. So here, we can simply call useState again to register a second state value for this component. And this also is an empty string initially, but then we get back two values again, or one value, one array with two elements to be precise. That's my enteredAuthor. And then my updating function, which could be called setEnteredAuthor. And whenever any of these two states changes, this PostsList component function will be executed again. In that case, the entire JSX code down there is evaluated again, which means that any nested component functions are also executed again. And that leads to precisely the behavior we want because that means that this post where we pass our updated state values, as values for its props to that post component function. This post component function will also be executed again if PostsList executes again. And therefore, these updated values which we pass as values to props to this component will be reflected in the JSX code of that component, and hence the UI will be updated accordingly as well. So that's how UI updates work with help of React and state. So therefore here, I now wanna pass my enteredAuthor as a value for the author prop for this first post component and then here in authorChangeHandler, I call setEnteredAuthor and pass event target value as a value. With that done, we just have to go to NewPosts and get rid of this paragraph with enteredBody in there, because we no longer have the enteredBody state in that component. And if you then save everything, you see that this component is empty by default, which should make sense because our default states for enteredBody and enteredAuthor are empty strings. But as soon as I start typing something here into these input fields, you see that the component down there gets updated dynamically with every keystroke because of state and because we lifted state up into a place where we can update and use it. Let's continue diving deeper into React. We get this form here, this input form and it looks decent, but I'd like to open it as a modal overlay. So as an overlay that's above the rest of the content on this page. And in the end, achieving this look is a pure CSS thing. Now what we could do is we could edit the stalls of this NewPost component such that it has this modal look. You can add a backdrop behind the form, so some background so that it looks like an overlay, but I'd rather take a different route. In the end, I wanna make sure that in the place where I use this new post component and I just pressed the auto format shortcut here to put these props into separate lines, which is still valid code but easier to read. But I'd like to take a route where I have a new modal component which doesn't exist yet, which can be wrapped around NewPost to give that NewPost that modal overlay look. Again, this modal component is a component we have yet to add, but I'd like to have a component that can be used like this. Now the idea behind that is simply that on more complex websites, chances are high that you have all kinds of content that should have that overlay look. Not just this new post forum but maybe also some warning dialogues, anything like that. So it would be nice to have such a wrapper and being able to wrap content with components of yours is indeed another core React concept. You can really only compose flexible powerful user interfaces if you're able to also wrap components with other components to apply some extra styles to them, for example. In the effort to achieve this year, I'll add a new component called modal. A Modal.jsx file is there for added and attached you find a link to a Modal.module.css file which you should add, which simply comes with some styles that will help us achieve that overlay look. And then inside of Modal.jsx, we can create a modal function and export that as a default. And then in there, I want to return a fragment, so this empty tag, where I have a div without any content inside and then a dialogue element that will hold the actual modal content. And this div will be used to render a background, a backdrop as it's also often called for this modal. Now we should import some CSS classes here from Modal.module.css and then assign one class here to this div, and that would be the backdrop class. And to the dialogue we should also add a class and that's the modal class. And backdrop and modal are both CSS classes defined in this CSS file. Now with that we have a modal component, but if we try to use it as a wrapper around NewPost, so instead of PostsList, if I go there, and I then try to import this modal component which we just added from ./Modal like this, and I then use it as a wrapper with the opening and closing tag around NewPost, you will see that it doesn't really look the way it should. It looks like the backdrop is visible. We have to gray background, this transparent black background everywhere, but the form and the modal is nowhere to be seen. The reason for that is that if you wrap content, no matter if it's a component or some default built-in elements, if you wrap content with another custom component by default, React does not know where to put that wrapped content inside the wrapping component. So inside the modal component, in this case. You have to tell React where that wrapped content should go, and you do tell React with another special prop. So with the props object, and that special prop is the children prop. By the way, instead of always using props dot, you can also use object destructuring here to directly get access to a specific value, so to a specific property of that props object. This is not only possible when using this special children prop, but it works with all props. So for the Post component, you could, for example, also use objected destructuring to get the author and the body and then save yourself the props.call down there. But that's just a side note. So this is just a more concise way of getting access to your props. What's new and important here is this special children prop. Thus far, we always added our own props. A post for example has our own author and body prop and these names were up to you. Now for children it's different, that's a reserved prop name because children always refers to the content that's passed between the opening and closing tags off your custom component. So here, this content, the NewPost component in this case, that's the value that will be received on the children prop in this modal component function. And we then output it down there, so that we tell React in the end here, it should output the content that's passed between the modal opening and closing tags. Now with that change applied, we just have to adjust the styling of this NewPost component here a little bit, and get rid of this box shadow border radius and margin, and also back in the modal component, add the special open prop on dialogue just like that. The value theoretically is true, but if you set true as a value for a prop, you can also omit it and just add the prop name and then true will be used as a default value. And this open prop is simply required by the default dialogue element to make sure it's visible. And with all these steps taken, you get that overlay with that form and it's above the other content. So that's great. That's now the children prop inaction helping us create a component that can be used as a wrapper around the another component. Now whilst it's nice that we have this overlay here, it's not that nice that we can't get rid of it, I can type something here, and you see that it gets updated in the background, but, of course, it would be great if we could close this modal somehow. For example, by clicking on that backdrop on that transparent black background. So how could we achieve this behavior? Well, in the end, again with help of state, you could say one state should be that the modal is visible and another state should be that it's not visible. And then, for example, by clicking on that background, we wanna update this state and switch it from is visible to is not visible. And then we wanna display this entire modal conditionally based on that state. So it's in the end a three step process, register and useState, add an event listener to this backdrop and then use that state to show or not show this modal. So to implement this, I'm back here in PostsList JSX, and I'll zoom out a bit since the code keeps on growing and there, we now don't just wanna manage these two values that can be submitted or entered through that form, but I instead now also wanna add an additional state slice here with useState. And the position does not matter if it's the first, the second or the last state, this does not matter. But here, the default value should, for example, be true because here I won't manage some text as a state value, but instead the modal is visible state, the name is up to you, but you should try to describe what's controlled by that state, and here, I wanna control the modal visibility. So I'll name it modalIsVisible and the updating function could be called setModalIsVisible and by default here it's true. So that we start with the modal being visible. Of course, this alone doesn't do much. We now also need to add some code to change this, if we click on this background here. Now to achieve this, we can go to the modal component because here we got that background, it's this div here, and there we can add the onClick eventListener, click is another default event. And onClick is there for a prop we can add to set up a listener to the click event on that div. And the function that should be executed should now not be defined here in this modal, but again in PostsList. So again, we're lifting the state up. Here, we can add a new function, showModalHandler, for example, or in our case, actually the hideModalHandler because that's what we wanna do if the backdrop is clicked. And here we can call setModalIsVisible and set it to false as a new state value. Now we have to pass this function as a value to the modal component here. So here, we could add a prop called onClose, it's your component, so the prop them is up to you and pass the hideModalHandler as a value to onClose, again without parenthesis passing the function itself as a value rather than the return value of that function, which is what we would pass if we would have parenthesis here. So we passed the function itself, and since I named the prop onClose here in the modal component, we can now also destructure this onClose prop here and set it as a value to onClick. So that this function which we receive on the onClose prop is set as a value for the onClick prop, hence wiring this click listener up to this hideModalHandler function in the end. Now with that we have a way of updating the state, but right now, we still wouldn't see any effect on the screen because we're not doing anything with that modalIsVisible state. We're updating it but we're not using it thereafter. And that's the last step, now we wanna render this modal conditionally based on our state. So the goal is to only render this piece of code here, this JSX code if modalIsVisible is true. Now how can we achieve this? Again with a dynamic value, so with single curly braces, but now we don't just want to output modalIsVisible. We don't just wanna output true or false, but instead we wanna control what's being shown on the screen. We could achieve this with ternary expression. If that's true, and for that we can also just check modalIsVisible, we wanna output this content. And indeed you can cut and paste that content here after the question mark, and then add a colon here since I'm writing a ternary expression where we also define what should be rendered if this is false. And that could be null. Null is something you can output as part of your JSX code and it will simply lead to nothing being rendered here. Alternatively, you could also set this to false and this would also render nothing. If I now save this, you see by default this is open, which should make sense because our default state value is true for modal is visible. But if I click on this backdrop, it disappears, and it disappears because I set the state to false, that's what we do here. And thanks to this ternary expression, it's then this L's case that becomes active and if you output falls or null here, nothing gets displayed on the screen in this place in your JSX code. The other parts like this list are still being output, but this content to be precise is now rendered conditionally with help of the ternary expression. Now there are other approaches as well. We could, for example, add a variable modal content and by default set that to nothing so to undefined and then check if modal is visible is true. And in that case, set modalContent to this JSX code. You can store JSX code in variables as well. You cannot just return it in functions, you can use it anywhere where a value is wanted. And then down here, in the JSX code we do return, we could now just refer to modal content and this would now either be nothing undefined, which also leads to nothing being output on the screen or it's this content. Now we are using a variable here, but we'll see the updated content nonetheless because we are using a state value which is updated with our state updating function here in the PostsList component. So this variable will only receive a new value if the state was updated with that state updating function and therefore, this component function was executed again. Hence, we'll see the updated JSX snapshot being reflected on the screen. So with that code, if I reload the page, it will still close if I click on the backdrop. And one last alternative, which I wanna show you though this year is a great approach since it's also quite readable, is that you go back here in your JSX code and instead of writing a ternary expression, you use the modalIsVisible state value again. And then the logical and operator here to then define a content that should be output if modalIsVisible is truthy, so if it's true in this case. Due to the way JavaScript works, it'll now output this content only if this value here is truthy, if it's true, and otherwise, it'll output nothing, or to be precise, it'll output the falsey value, false in this case. And that as you learned will lead to nothing showing up on the screen. So here, we're using standard JavaScript to render nothing or the modal. So that's another approach of making sure that we can hide it. And no matter which approach you prefer, all three approaches are fine, but that's how you can render content conditionally. So at this point, we can close the modal if we click the backdrop, but we can't open it again. Now to open it again, I wanna add a header component above my list here, which gives me a button that allows me to open this modal. Now I prepared such a component in advance since it won't include any new features we haven't learned about yet. Attached you find a MainHeader.jsx file and a link to the MainHeader.module.css file and the MainHeader.jsx file simply defines a MainHeader function where I got some JSX code. Now one noteworthy new thing is in there though, I'm importing some icon components from a third party library. And at the moment, this library isn't downloaded into this project here. To make sure these icons are available here, and this import command here works, you should quit your development server by pressing Control + C and you should then run npm install react-icons to install this React icons library into this project. This makes it available as part of your code base and importing these icon components will then work and thereafter, you can run npm run dev again to bring up that development server again, which you must have up and running as long as you are working on your code. So with that, we got that MainHeader component and now this MainHeader component should be rendered above this PostsList. For that, I'll actually go into the app JSX file, and in there, I'll import MainHeader from component's MainHeader and then return a fragment which wraps this main section and PostsList and render rendered a MainHeader here above the main section. With that we got this MainHeader here, but this button of course doesn't work yet. To make it work, this button now also needs to set this state that shows or hides the modal. The modal is visible state, however that state is an PostsList component. But you learned how this problem can be fixed. You can lift the state up. We can cut this state from PostsList and move it into the App component. And there, we then also must import useState from React to make that useState hook available there. We then also must cut the hideModalHandler function and move that to App and also already add a new function called showModalHandler, which does the opposite of hideModalHandler. It simply sets ModalIsVisible to true again, and now we just need to make sure that the information, whether the modal should be visible or not is available in the PostsList component. Now to make it available there, we can use props again. We can add a new prop is posting could be the name. You could also stick to modalIsVisible alternatively, but here, I'll use isPosting as a prop name, and that should be true or false, and I'll use it down there in my conditional rendering code. So if this is true, the modal should be displayed because if I am posting, I'm working on a NewPost. So then this form should be displayed, and if it's false, it should not be displayed. And in the App component, we can now set this new isPosting prop on PostsList and simply forward our modalIsVisible value. So set the value of this state as value for this prop, and with that we're passing the information whether the modal should be visible or not to PostsList. Of course, now we also must make sure that we can talk into the opposite direction. So if the modal is closed, we wanna trigger hideModalHandler if the backdrop is clicked, for example. And in the MainHeader, if the button is clicked, I wanna show the modal again. Now here in MainHeader, I already do expect to get a onCreatePost prop, which I forward to onClick on that button. So here, I wanna have a pointer at that function that should make the visible. So therefore back in App JSX, we can add the onCreatePost prop to MainHeader. We can set that prop and set it to showModaHandler, so to this function, so that this function is passed as a value to onCreatePost, and on the PostsList component, we could add another prop called onStopPosting, and here, pass the hideModalHandler function as a value. Now we just have to make sure that we use this onStopPosting function in PostsList and therefore there, again, we can accept it as a new prop. And then here for modal for the onClose prop, we now pass the onStopPosting value to the modal component. So that in the end, the onClose prop of the modal component receives this hideModalHandler function and passing these different functions across multiple levels of components and passing these different state values around, of course, can be confusing at first. So therefore, it's just important to keep in mind that in the end, we're just passing values around so that in the different components we can use exactly the values that should be used there. By the way, the fact that my custom props here that take functions as values like onCreatePost are called onCreatePost is just a convention I'm following. I could also just name it createPost and update the name here in MainHeader, of course, and that would work as well. However, it's a common convention to start with on in your prop name. If that prop is receiving a function as a value. To in the end make it clear that this prop won't work with any other value and in the end will typically link that function that is received as a value to some event listener further down in your JSX component code. However, now with all these changes made, if you save all your code, we can close that modal and we can also open it again, so that's now working. And therefore, now back in app JSX, we can also switch the default for modalIsVisible from true to false to make sure that initially if we reload this page, no modal is visible, but if you click that post, we see it. And then there, we can still add it and add our text as we need to and update this first post. And therefore, that's yet another huge step forward with more state passing across different components. And with that, we're now ready to dive even deeper into React and make sure that we're now not just updating this first post here, but that instead, we can really submit that form, and once we do so, we actually added this list of posts so that we finally can start adding new posts instead of just editing the first one. So let's now make sure that we actually have a form where we have a submit button and maybe also a cancel button to cancel editing and close the modal, but that we have a submit button, which when pressed adds a new post and our list or our grid of posts then keeps on growing as we add more posts. To achieve this back in the NewPost component. We first of all, have to add some buttons there. For this, here at the end of the form, we can add a new paragraph which should receive a class name of classes.actions since I prepared a class named actions in the CSS file, which then will style these buttons accordingly. Now in this newly added paragraph, we should add two buttons. Now the second button will have a caption of submit. The first button will have a caption of cancel. However, by default if you add buttons to a form, if they are pressed, they will submit that form. This means that a submit event will be generated and also that by default the browser will generate and send an HTTP request to the server that's serving the website. Now we don't want that and will prevent it therefore, because we wanna handle the input with our client side code instead with React instead, not with server side code here. But besides that, I also wanna make sure that not both buttons submit the form, instead, only the submit button should do so, not the cancel button. To make sure that the cancel button does not trigger form submission, we can and should give it a type attribute which we set to button. The alternative which we can set on the submit button is type submit. But this is not required since status to default anyways. Now this button button here will now not submit the form when clicked. Instead, it should close the form. And to ensure that it does, I'll accept a new prop here. And I'll actually also use object destructuring here to get my onBodyChange and onAuthorChange prop so that we can get rid of props.here in these two places. But I'll now also accept a new prop as mentioned, which could be named onCancel. Name is up to you. But I do expect to get a function on this prop because I wanna connect it to the onClick prop here so that in the end, an event listener is set up triggering the function, which will be received on the onCancel prop. Now this onCancel prop therefore must be set here on the NewPost component and it should be set to a function that will close that modal. Now for that we have to onStopPosting prop, which we're already receiving here on PostsList, which if you remember will in the end trigger hideModalHandler, which is exactly what should get triggered. So I can reuse the onStopPosting prop here, and set it as a value for the onCancel prop. So with that, if we save everything and we open our modal, we now got these buttons and if I click Cancel, the modal closes. But now let's make sure that we can also submit that form. So how can we now handle form submission and what should happen when the form is submitted? Well, in that case, I of course also wanna close the modal, but I also wanna get the two values that were entered and in the end add them to my list of posts. And the list of posts should then also be output dynamically instead of having these two pseudo hard coded posts here. So let's handle this step-by-step. First of all, in the NewPost component on this form element, we should add an event listener, a new prop called onSubmit to listen to the default submit event, which is a default event supported by the browser out of the box. Now we need a function that should be executed when that submit event occurs. And I wanna have that function in the place where I also collect the values that are entered. Now in my case here, these values are managed in PostsList, but actually, we don't need to do that there anymore. I'll instead bring them back down to NewPost to the NewPost component. So I bring my state slices back there, and therefore here, we now import useState from React again. And I don't need these state slices in the parent component, in the PostsList component anymore because I don't want to use them for setting my post author and body here anymore. Instead, I'll get rid of that post for the moment and soon I wanna dynamically render a list of posts here anyways. So therefore, we can also get rid and we must get rid of onBodyChange and onAuthorChange on the NewPost component. And to clean things up, I'll also get rid of that code here, and PostsList, therefore is now much leaner. But in the NewPost component, I now wanna call bodyChangeHandler again if my textarea changes. So I will set bodyChangeHandler as a value for the onChange prop here on textarea. And for input, onChange, I'll set is to AuthorChangeHandler so that in the end these entered values are managed as state in the NewPost component again. And these two props onBodyChange and onAuthorChange are not needed here anymore. Now we also must add a function that should be triggered when the form is submitted. So I'll add a new function here, submitHandler could be the name. And this function is passed as a value to onSubmit. Now here, just as with the other event handler functions, we get an event object automatically, since it's set to onSubmit, so to this default submit event. And now we gotta do one important thing here for this submit event, because as I mentioned before, when a form submitted, this submit event will be triggered and the browser will automatically generate and send an HTTP request. And we don't want that here, because sending an HTTP request to the server that's serving this React app would in the end lead to the page being reloaded. And we have no server side code here that would handle that request. React is a front end library running in the browser, not on the server. It can't handle that request. Therefore, we have to use this event object and call the built-in prevent default method written like this. This prevents the browser default of generating and sending an HTTP request. With that done, we can then thereafter collect and group the enteredBody and enteredAuthor values into a postData object, for example. A default JavaScript object where I add a body property, which can be set to enteredBody and an author property which can be set to enteredAuthor. We could also add some client side validation here and update some state to show an error message if invalid data was entered. But whilst that is something we do in the complete guide, it's not something we'll do here in this crash course. Instead we'll just assume that the provider's data is valid and we'll rely on the default browser validation added with help of the required attribute. And we therefore now got our postData here and now that postData in the end should be added to a list of posts, which should then actually be rendered as a list of Post components onto the screen and that's what we'll do next. This is however how we can handle form submission and we can see that it works if we then console log our postData here like this in the submitHandler. If you save all your code and you make sure that the modal is open and you open the developer tools thereafter, you can enter something there. And as you click Submit, you get this object here with those entered values. So that's working. And now I just wanna make sure that this modal gets closed if I submit this. So therefore thereafter I'll call onCancel as a function like this. Keep in mind, onCancel is this prop which receives a function as a value, and therefore, we can execute it as a function here. Hence executing that function that is received as a value on the onCancel prop. And that function simply turns out to be that hideModalHandler function. So that's the function where in the end executing here. So with that, if we try this again and click Submit, now the modal closes. So let's now make sure we output that list of posts. So we're gathering that postData, how can we now add that as opposed to a list of posts that should then be output dynamically here instead of outputting this hardcoded post here? Well, in the end, again, by using what we already know, plus two new concepts or features. In the end, we have to get this postData from the NewPost component to the PostsList component. And there, we then should manage some state, which in the end manages a list of posts. And whenever that list changes, we wanna update the list for outputting down there. Therefore, we can useState here and import useState from React in the PostsList component and pass an empty array as an initial value. And that then should be our posts array with a setPosts state updating function. So the idea is that here we manage a list of posts and that lists should be edited whenever we submit a NewPost. So therefore, we also must add a function here in PostsList, which adds a NewPost. And that could be the addPostHandler function, and I name it addPostHandler because in the end, again, it should be triggered whenever the form is submitted in the end. Now here we could expect to get some postData and then we wanna update our post state with setPosts here, and in the end, pass a NewPost object to this array. Now for that, what we could do is pass a new array as a new state value to setPosts and then add postData as a new value to that array and to make sure that any potentially existing posts aren't lost, we could use this spread operator, a default operator built into JavaScript to spread our existing posts into this new array of posts so that we add this NewPost as the first element in this array and the existing posts come thereafter. This is not optimal, but it will work. So now we just have to make sure that the addPostHandler is executed as the form is submitted. For that, we can pass this addPostHandler function with help of a prop to the NewPost component. So we could add a prop called onAddPost and set the value of that prop to the addPostHandler function we just added. And inside the NewPost component, we can now use the onAddPost prop, again using the same mechanism we've used over and over again to accept that prop here and destructure it from this props object. And in submitHandler before calling onCancel, we can now call onAddPost since this again is a prop yielding of function and passing the postData to this function. And this function that is executed in the end is this addPostHandler function. So this will now add this post to this array of posts. But as I mentioned, this code here isn't ideal, because there is a rule. If you update state and that new state is based on that previous state value as it's the case here, where the new state is based on the existing posts, you should actually pass a function to setPosts. For example, an arrow function. And this function here will be called automatically by React whenever you call setPosts. And this function will automatically receive the current state snapshot, so the existing posts and you should then return the new state value where you could, for example, again add your postData and spread the existing posts. Now this looks very similar to what we had before, but it's the technically better way of updating your state if it depends on the previous state snapshot. The reason for that is that internally, React does actually not execute your state updating functions instantly, at least, it's not guaranteed that it will do so, but it schedules those state updates and in case, you have multiple state updates after each other, you could potentially update your state based on some old state or anything like that. And therefore, this way is a way of making sure that React ensures that you get the latest correct state for this state update, even if you have multiple pending state updates. So therefore, it's this simple rule. If the new state depends on the old state, then you should use this function form for updating the state. You get the old state automatically, you can use it, and you should return the new state then as a value and you can use the old state if you need to, as it's the case here. And this does not just apply if your state is an array, but whenever your new state depends on the old state. And with that, we're managing this list of posts. How can we now output it down there and render one post component per post item in this array? Well, to output this post component for our different array items, we have to add this dynamic expression here again because we wanna refer to our post state here. And now in the end, we wanna transform our array of post objects into an array of JSX elements, one post element per post object. Because if you output an array of JSX elements in your code. For example, here's some dummy paragraphs that will actually be rendered to the screen as you can see here. So you can output an array of JSX elements in your JSX code with these single curly braces. So therefore, we could output the posts array, but that would be an array of pure JavaScript objects, not of JSX elements. But in the end, you must output JSX elements down there. Therefore, you can call the built-in map method on this post array. This method exists on all JavaScript arrays and this method takes a function which is executed by the browser for every item in this array receiving that item, and then you return the value to which this item should be mapped. So map returns a new array where every item in that old array was transformed into a new item into a new value. And here, I wanna transform every post in my post array to a Post JSX element. That's some code you can write here. And in the end, this will yield us an array full of JSX elements. So this function here is executed for every post in Posts and therefore, now we just have to set the author here to post.author and the body to post.body. And we can access .author and .body on the post object in the post array because the postData object which we add to this array comes from onAddPost in the end since that's the prop receiving the addPostHandler function. And this comes from NewPost, and there it's this postData object we have here, which we pass in the end to addPostHandler. So it's this object with this structure that's added to the posts array. And here, we have a body and an author field, and therefore, here we can access .author and .body. And with that, if we save that, we got no posts initially, but I can add a new post like this, click Submit and it shows up here. Just like this. So that's how you can dynamically output lists of items. However, if you open the Developer tools, you'll notice that we get a warning here, that each list item should have a unique key prop, that's a requirement by a React, which the end ensures that React is able to render and update lists efficiently. I talked more about that in my complete guide course. In the end, whenever you output a list like this. So if you map an array to an array of JSX elements, you should add the special key prop to the JSX element, which is not a prop you must accept or use in your component. The post component doesn't use any key prop here, but you can still add it to every JSX element because it's a special built-in prop supported by React. And this prop should receive a value which is guaranteed to be unique for every post. Typically, there should be some unique ID here we could use the post body, which in theory could occur twice for two different posts, but which is good enough for this demo. And with this key prop added and set to post body, you also see that if I reload and test is again, the warning does not show up again. So that's how we can output a list of posts with help of this map function and with help of managing our posts with state. Now, to finish this first version of this app, I just wanna make sure that I also show a message if we have no posts yet. And in the end, that means that in my PostsList component where I output a dead list of posts, I just have to render this unordered list conditionally with a dynamic expression where I check if posts.length is greater than zero, which means it is an array that has at least one post. And if that's the case, I then want to output that unordered list using this conditional rendering approach you learned about before. And then I add another expression where I check if posts.length is equal to zero. So if I have no posts, and in that case, I'll render a div. Where I'll just add some quick in there inline styles where I set textAlign to center with this syntax and color to white. And inside of that div then h2 element where I say, there are no posts yet. And below that a paragraph where we could say, start adding some like this, textAlign is written like this instead of text-align because this would be an invalid JavaScript property name, therefore you have to use camel case notation. And with that, we now got this fallback text, but as soon as I add a NewPost, this disappears and my list of posts shows up instead like that. So that's working. And with that, we now learned about a lot of key concepts that you must know if you wanna work with React. But it's not all we can do with React. Instead, it's now time to dive into more advanced features. By now we learned a lot about the most essential React features you must know to get started building reactive user interfaces with React. But the demo app, the demo website we built thus far, of course, only works in the browser. There it works absolutely fine, but if we add posts and we then reload this site, all the data is lost because at the moment it's only stored in memory whilst this React app, this JavaScript app in the end is running in React. And that's really important is a front end JavaScript library. You use it to build a user interface, it powers your web user interface with JavaScript in the end and it therefore executes in the browser. Indeed, what we're building with React.js in most cases is a so-called single page application. An application, a website where we in the end have only one single HTML file, this index HTML file here, and then everything that happens on the screen is powered by JavaScript. So if we open a modal here, that's not a new page, not a new HTML file that's being downloaded or opened. Instead it's the existing page being edited by JavaScript, the DOM being edited by JavaScript. If I view this page source here, I just see the basically empty HTML file, this index HTML file that was downloaded initially. But in this file, we have this script import, which in the end imports our JavaScript, our React application, and it's that application that then edits the DOM so that the actually rendered DOM has far more elements than the initial HTML file. So we use React to build this interactive front end, and in the end what we're building is a single page application. But it would of course be nice if the posts that we create here would not just be stored locally in memory so that they're lost whenever we reload this and so that also no other users can see them. But if we instead had some backend to which we can send requests and from which we get back responses where the data could then be stored in a actual database. So with backend, I mean a separate web application, a web API, a REST API, for example, running on some server, so not in the browser of our users but on some server owned by us, for example, and that backend API, that REST API could be built with any language or framework of your choice, not necessarily with JavaScript and typically not with React, since React is not really a backend library, I'm saying not really because there are frameworks like Next.js or a Remix on which I also got courses that build up on top of React and allow you to blend back and code into your React app. But React itself is not a backend library, instead it really focuses on allowing you to build interactive user interfaces as you learned. But we still might want to be able to store data on some backend, in some database, for example. And for that we need such a backend API, either a third party API or an API built by us, and then that API, that backend service could interact with files or with databases or anything like that, so that our front end application, the React app then can send HTTP requests to that backend so that some data gets stored there or so that we fetch some data from the backend, which is then returned to the frontend through an HTTP response. That is something we might want for this demo app here, and for that reason attached, you find a link to a dummy backend project, a dummy REST API in the end built with node and Express.js. So no React code here, and you don't need to know Node or Express to follow along because this backend API is already finished. And what I'm doing here in this backend API is I'm storing some data in a Post.json file. We could also use a database, but that would simply require some extra setup. So for it is demo, I'm just using this file. We're storing some data there and we're fetching some data from there. And I provide various REST API endpoints that allow us to get a single post or create a NewPost. And then I got all the logic for doing those tasks in here in this API. And therefore, if we start this backend server locally on our machine for this demo, we can add code to this frontend application to this React application for it to reach out to this backend. And, of course, if you would deploy this, you would have two different servers with two different domains. Here, we can run both on our local machine and simply use different ports to simulate different servers and domains. This backend application listens on port 8080, and we can start it by first of all, running npm install to install all the dependencies that are required and then running npm start to start that node server. And just as the frontend development server, you should keep that server up and running as long as you wanna be able to send requests to this backend. So now with that backend up and running, we can go back to the frontend and add some code to it that allows us to send requests to that backend to create NewPosts, and, of course, to fetch posts as well. So how can we send requests from inside our React application to a backend? Well, let's start with creating NewPosts. For that, we got this NewPost component and there at the moment I have this submitHandler where I in the end call onAddPost and pass the collected postData to the parent component of NewPost. In this case, that's the PostsList component. There I'm using the NewPost component and onAddPost, we're executing this addPostHandler where at the moment, we're updating this local post state. Well, we definitely still want that local post state because we still want to render some posts, but we also wanna send that data to the backend. And in that backend code, just as a side note, this API route should be hit. A post request should be sent to this path on the backend. And there, this post will be stored in a file in this post, JSON file enriched with an extra pseudo unique ID. But that's just a side note. So that's the path to which a request should be sent. And two do that, we can use the fetch API. The fetch function is available in browsers out of the box. It's not a React feature, and fetch can be used to send HTTP requests. And unlike the name suggests, you cannot just use it to fetch data but also to send data. It's a bit confusing, but that's what you can do with that fetch function. Now fetch takes the URL which you wanna send a request, and in my case that's localhost 8080, localhost because this backend runs locally on our machine, and 8080 as mentioned is the port on which we listen on this backend server. So we send a request to this URL or to this domain and then there specifically we want to target the /posts path here because as I just mentioned, it's this /posts path here where we expect a post request if we wanna store a NewPost in this file. Therefore we also have to configure this request because by default fetch sends a get request and we can now pass an object as a second argument to fetch to set the method to post to turn this into a post request and student then also add a body, so the data that should be attached to this outgoing request. And here, the data I do wanna send is my postData, of course, the data we're getting here, but we have to convert this to JSON, so to the JSON format, which we can do with the built in JSON object and the stringify method. With that, we turn that data into JSON as we must do. And then last, but at least, we should add some headers to this outgoing request by setting an object on this headers property. And here, I wanna add the content type header and set this to application JSON. And that's how we could send such a post request with our postData to the right path on this dummy backend. Now fetch will then send this request, hit this API route here, this API resource, and then ultimately, it will return a response. Now for the moment, I'm not really interested in the response here, and therefore, we can just save this and if we do so and I add a new post, Test, Max. It still appears locally because I still update my posts as I did before. But if we switch to the backend here, we should see that in posts JSON, we also get the post here. So it was indeed received on the backend and stored there. And that's generally how we can send a request from our frontend to the backend, nothing special about that here. It's the standard fetch function and it does what we would expect. But, of course, we now also wanna fetch data. We wanna make sure that if we reload this page or if we visited for the first time. We fetch the available posts from the backend, and here, things become a bit more tricky. So how can we fetch posts when we first visit or reload this page? Well, for that, you could of course say that you go to PostsList because that's where we need to posts. And we also send a fetch request here, we target the same URL as before because if we take a look at the backend, we see that in the end the get request to /posts gives us all our posts and then here, we already send a get request. 'Cause as mentioned, that's the default for the fetch function. So we don't need to configure this request. And now what? Well, now in the end, I wanna make sure that we update our posts here whenever we got a response. Well, for that you could try to use async await like this, but this is not really supported. Your component functions must return JSX code or some other values, but promises should not be returned at least for this standard component here without using any extra framework on top of React or anything like that. So promises may not be returned and since adding async in front of a function always ensures that this function returns a promise because any data returned by the function gets wrapped into a promise. We must not use async here, and we therefore can't use await here. But, of course, we could use the standard old school way of handling the response and add the then method here to get our response and then return response start JSON to unpack the data from the response because that's how you do it with this response. There is a JSON method, which then ultimately gives you the data that was sent back from the server and that data that sent back is an object with a post key that holds all the fetched posts. So we could add another then block here, and then access data.posts and dare to be precise, we might want to call setPosts and set our posts to data.posts, but we should not do that. You should not save that. You should not write this code. Because if you would write this code, it theoretically would update the state with the NewPosts, but it would cause an infinite loop. And why would it do that? Well, simply because whenever you update your state, as you learned, your component function gets executed again by React. That's one of the key ideas of React that updating the state causes the component function to be executed again so that React can update the UI if needed. However, if this component function executes, again, this fetch request also gets sent again. So we send another request, we get back data, we update the state, and the loop begins again. So this is not code we wanna write like that, it would cause an infinite loop. So therefore, since that's not the solution for fetching the post, how should we do it? Well, this is of course a common problem and therefore React has a solution. It has another hook we can use. Now the hook we can use to solve problems like this where we effectively wanna cause a side effect in our component function, so where we wanna trigger some action that does not directly influence the JSX code, but maybe indirectly in the future or that does anything else that's not related to rendering the UI. In such cases we get another hook we can use and that would be the useEffect hook which is there to wrap side effects. UseEffect allows you to safely run code like this without causing an infinite loop. But how does it work? Well, you execute useEffect like this and unlike useState, it does then not return a value. Instead it takes a function as a value and as a second argument and array. So two arguments that must be passed to useEffect, a function and an array. Now I'll come back to the array in the future. Let's first focus on the function. This function will be executed by React for you whenever it considers this effect to require execution. And I'll get back to when it considers this effect to require execution in just a couple of seconds. But I can tell you that this second argument, this array has something to do with it. We can however now grab our code and put it in there and we could now also actually wrap it into an extra function. FetchPosts could be the name, which is an async function, which is the defined inside of the effect function so that we can move our code in there and actually use await to get our response and then also get our response data by awaiting response.json so that we have this more readable code and then we update our posts with a resData posts. I created this extra function in this effect function instead of turning the effect function itself into an async function, because useEffect takes a function that should not return a promise itself, but that instead should return nothing or a cleanup function, which is not too important for us here, which I do of course cover in my complete guide course, but which we can't ignore here, but we should not return a promise here for this effect function, and therefore, we should not add async here. Instead, I create an inner nested function, which I then simply immediately execute inside of this effect function. And this trick allows me to use async await in here, but back to the effect function itself and the idea behind it. As mentioned, React will now decide when this function gets executed, and therefore, when this function gets executed indirectly, and I can't tell you that now with this setup here, it will not always get executed when this component function executes. Instead of we save this code and we reload the page, you see that now this post appears magically and that's of course the post from the backend and we can prove this. If I go to the backend and I would edit the body here in post.json and safety updated file, and I then go back to this app and reload. You see that was updated here as well. So this data is coming from the backend thanks to useEffect, but how exactly is this function working and why is it now not causing an infinite loop? This useEffect function here, this hook is now preventing an infinite loop from occurring by simply making sure that this effect function does not always execute when the component function executes. It executes sometimes when the component function executes otherwise we wouldn't have fetched the posts, but not always, but when does it execute? Well, that's controlled with this second argument that's passed to useEffect, this array here. This array in the end specifies the dependencies of your effect function. And a dependency is simply any variable or function that might be defined outside of this effect function anywhere in your React components in this component or some parent component passed down through props. And whenever such a variable or function defined outset of the effect function changes receives a new value, for example, this effect function will be executed again. Now if we have an empty array, it simply means this function has no dependencies and therefore, it will never be executed again. Instead, React will only executed once and that's when this component is first rendered, and technically it gets executed after the component first rendered. So theoretically, the component first renders without any posts and then it immediately executes this effect function where the posts get updated. But that's all so fast that we only see the final state here where the posts are fetched. But that's how this executes and this now gives us fine grain control over when this executes. So that's how we can handle side effects like sending HTTP requests. Again, we of course dive deeper into effects and all these things in my complete guide course because that's the idea behind that course. But that's in a nutshell what you must know about useEffect and how it can help you. For example, for fetching data when a component is first rendered. Now we added the useEffect hook to fetch data and this is all looking good. And if we load this page, the data shows up pretty much instantly. Now that's also the case because the backend is running on the same server, on the same machine, our local machine as the front end, and therefore, this HTTP request and all these things are happening super fast. In reality, sending that request here for fetching or for storing the data might sometimes take some time. It's not that bad because in the end here we are fine with still updating the posts in our local state immediately and we just send this request kind of behind the scenes and it doesn't matter if it takes a second or two, but for fetching the data, it would be bad if the backend would be a bit slower. We can simulate this by going to the backend code. And there, you find this line of code in the get posts route here in this function, which you can comment in. This simply adds a delay. Of course, it's not realistic that you would add such a delay, but this is just for demo purposes to simulate a slower backend. If you comment this in and save this file, you can quit this server with Control + C, and restart it to make sure that those changes are taken into account. And now you will see that if I reload this page, I see there are no posts yet first before the data shows up. And this is not necessarily the ideal behavior, because the user doesn't really see what's going on and it looks like there really are no posts until suddenly they do show up. You instead might wanna show some loading text or loading spinner whilst the user is waiting for the data so that we differentiate between scenarios where we have no data and where we're simply still waiting for the data. And to achieve this, what we could do is in PostsList, we can add another new state with useState, and that would be a state which I'll name is fetching with the set is fetching state updating function. And initially that's false, so it should be a bully and value. And the idea is that we set this to true right when we start fetching our posts in here and we set it to false thereafter. With that, we have this fetching state and we can use that to show an alternative UI whilst we're fetching data. So in the JSX code down there, we only wanna show the posts or the fallback text if we're not fetching. So if we're not fetching, if this is false and post length is greater zero, we wanna show the posts. And similarly, if we're not fetching and post length is equal to zero, we wanna show the no posts text, because and that's a new scenario if we are fetching, then I instead rather wanna show a paragraph where I say loading post dot dot dot something like this and I'll wrap this into a div here which also centers this, and turns it into some white text like this. With that, if we save this, we now see loading posts initially until the posts appear, and that arguably provides a better user experience than showing this. There are no posts message instead, which is technically wrong. There are posts we're just still waiting for them. So that's how we could handle a loading state and that's another improvement you might wanna add when fetching data like this. Now that being said, there are more things we could improve here. We might also want to handle some error state and check if the response is maybe not okay, so if we had an error response and in that case output an error message, and you can definitely try doing that as an exercise. Here, I'll not do it because this is just a crash course getting you started, it is an improvement you might wanna add, but I'd rather dive into more advanced and useful React features, which is what we'll do next. So we got data fetching and data sending and this demo website data for looks quite nice, quite decent, and we learned a lot about React. However, there's one last crucial feature missing in this website, which I'd also like to explore together with you, and that would be routing. Now what's routing? Many React apps, I would say almost all React apps, at least definitely if they are anything but simple demo apps might want to have routing, which simply means that you wanna support different paths and load different pages, different components in the end for those different paths. At the moment, our demo website here only has one path, no matter if I click new post or not. The path up there, the URL always stays the same. The disadvantage of this is that I, for example, can't link users to this new post mode. If I want to send a link to someone that allows them to immediately create a new post, I could try to copy this URL, but if I paste it in and hit Enter, I end up on the starting page again, because this React app has no pages. And that should generally make sense because as mentioned before, we're building a single page application with React. So we have only one page, only one HTML file, but the idea behind routing is that we can still support multiple paths by simply listening to URL changes whilst the app is running or by evaluating the URL when it's first loaded, and by then loading different components for different paths that are encoded in the URL, so that for our domain/nothing we load the landing page for /products, we load the products page and so on, that's routing. And even though React apps are SPAs, as you learned, there is a solution for still getting this behavior. And that's the React Router package, which is the most popular routing package for React because React itself has no routing capabilities built in, and whilst you could build your own solution where you try to take a look at the URL extract the path and load different components for different paths, React Router is a powerful package that solves all these problems for you and that offers tons of features related to routing. Now just as with all the other React parts, I dive way deeper into React Router in my full course, but will still get started with this super useful package in this crash course here. Now React Router also has an official website where you of course can also learn all about it. And it's also worth mentioning that there are different versions of this package. And for example, version five is still quite popular, but version six, for example, works quite differently compared to version five. And therefore, I also got separate videos where I explain what's new in version six and also in 6.4, which also added even more exciting features to React Router. It is crash course, we're of course going to dive into that latest version here. And for that, we first of all have to quit our development server here in the front end application and run npm install react-router-dom. So not just React Router but React Router DOM, this package must be installed and that gives us React Router in this front-end application. Now with that, we can add routing, and what's really important to keep in mind is that we still have a front-end application. This routing happens on the client side, not on some backend. But it does still enable us to support different paths and simply load different components for those different paths. Now which different paths could we support in this demo website? Well, of course, I still want to have the starting page where I show all posts, but I then also wanna be able to get to this new post page here. So that should be a separate page, maybe still presented like this as a modal overlay, but it should get its own path, its own URL. And I also wanna be able to click on my posts to load them in a modal on a detail page as well so that I can also link to a single post if I want to. So I wanna have these three routes, starting page, new post page and post detail page if I click on a post. And therefore, we need to tell React and React Router that we wanna have these three posts, and we can do so, for example, in main JSX, by first of all, they're importing something from React Router DOM and there's something we wanna import is the RouterProvider component as it turns out. And you should render that component instead of the app component here. This enables routing and tells React Router that it should watch the URL and start rendering different components for different paths, but just by adding it like this, it won't work. And that hopefully makes sense because of course you also must tell React Router which components should be loaded for which paths. So you must configure the Router, that's why RouterProvider takes a router prop, which wants a route configuration object as a value, and that configuration object is created with a function imported from React Router DOM, which is called create browser Router. We can then call this function to create such a route configuration object and store that in a constant and pass that constant, that configuration object value as a value to the Router prop on RouterProvider. And now create browser Router then takes an array as a value, and this is simply an array of all the routes you wanna have, a list of route definitions and a route definition is simply an object, an object which typically should have a path property where you, for example, define the path of a single route. So we could have multiple objects here and every object represents one route, one path, and the component that should be loaded for the path. So here, we could have the path slash nothing as the main route so to say, which then is loaded for our domain slash nothing which is equal to just entering our domain. So that's of course one important route we wanna support here. And the path alone is not enough. Instead, you should also add the element property where you now define the JSX code that should be rendered on the screen when this route becomes active. So when this path is active, and here, in my case that is simply the app component for the moment. So the component which we previously rendered there is now the component that should be rendered if the path is slash nothing. With this simple change, if we save everything, the app still works as before because we load this app component for slash nothing. So that's of course not too impressive. But if I for example, enter /new, I get an error instead, which already proves that something is going on here. React Router is doing something because indeed it is telling me that it did not find this route and that makes sense because I only defined this slash nothing route, but that still works then. But, of course, we don't just want to add one route, we wouldn't gain much by that. Instead, we wanna have multiple routes, and for example, we wanted to have a separate route for creating NewPosts. So how can we add this NewPost component as a separate route? Well, we can of course add a second route here to this create browser Router function and then maybe have a path of create-post. This path is of course totally up to you. And then here we could say that we wanna render an element and the element should be the NewPost component. For that you must import the NewPost component, but then you can render it like this, and you can by the way, render any JSX code of your choice here, could also be some h1 tag, but of course here in that case I wanna render the NewPost component like this. Now if I do that, and I then enter create-post here, I indeed see this new post component here not as a modal and the rest of the app is gone. And it also doesn't really work, because upon submitting this prop value is not received anymore. This value for on at post is not received anymore because I'm using this component now without setting any props, but it technically generally still works. At least I can see this component, but, of course, it's not rendered the way I'd like to see it. Instead, it should still be rendered as this overlay and this button should of course still lead there. And, therefore, we have to dive into another important feature offered by React Router and that's the feature of creating layout routes. When building more complex React apps with routing, it's quite common that some routes should also have shared layout elements. For example, this main navigation bar here at the top, should probably be visible on all routes we have. And to achieve this, you can add so-called layout routes, which are actually just normal routes, but routes that nest other routes inside of them. To add such a layout route, we could add a new route definition. The position in the array doesn't really matter here, but I'll add it as the first route. And then here the path is still slash nothing because I want to create a layout that wraps all routes no matter which path they have. Then we have to add an element, and here, I need to add a new component. And for that, I'll actually add a new folder called routes to organize my components differently now. The components which are used as root should go into the root folder and the other components which are used somewhere else will stay in the components folder. This is not needed technically, but makes this app a bit easier to maintain and understand. In this routes folder, I'll add a RootLayout JSX file, though the file name of course is up to you. In there, we create a regular component function, which could be called RootLayout and which is of course export it. And then here I wanna return a fragment where I have my MainHeader and then something else which I'll add soon. For a moment, it's just a MainHeader, and that should be a layout route which is wrapped around other routes so that the MainHeader is shared and then the content of the other routes is rendered below this MainHeader. To make this work back in main JSX, we can import the RootLayout route from routes RootLayout and set this as an element here like this. And now the important part that must be added here to make this a layout route is that we add another key to the route definition and that's the children key, which takes an array and it takes an array of more route definitions. And here, I'll then move these two route definitions into this RootLayout route definition, and that turns this RootLayout route definition into a layout route of these two routes. Because these two routes are now nested routes to this route here, and they share the layout provided by that route. They simply are inserted into this RootLayout component, and therefore, they share this MainHeader. However, if we save this, you'll see that, yeah, the header is there, but the content is missing and clicking NewPost also doesn't do anything. The reason for that is that indeed we are now sharing this MainHeader component, but we're not telling React Router where to render the content of these nested routes. And that is of course something we should do. And we do that by going to the RootLayout and importing an outlet component from React Router DOM. That's a special component provided by the React Router package, which should be rendered in the place where the actual nested route content should be rendered, should be injected, so to say. So this is simply a placeholder where the nested routes can render their content in the RootLayout and therefore with outlet added here in RootLayout below the MainHeader. If we save this, we now got the app component content back. Therefore, I now also have two headers here because at the moment the app component of course still brings its own MainHeader, but that's what we can tackle next. It's now time to refactor the code a little bit and clean it up a little bit to make sure that we don't have this duplicate header here, for example. So let's do that cleanup work. And I first of all wanna make sure that this app component is a separate route in the end. And for that as a first step, I'll actually move app into the routes folder because this is loaded as a route. And wanna as mentioned before, organize my component such that route components are in the routes folder and other components which are used as part of our components are in the components folder. And I'll rename this app component here to posts because ultimately this should be responsible for rendering my PostsList here. Now in this posts JSX file, which was the app component, I'll remove the MainHeader and I'll rename this function here, this component function to posts also in the export, and we can get rid of that MainHeader import here as well. Now we can also get rid of the showModalHandler because that was previously used by the MainHeader, and we can actually also already get rid of HideModalHandler here, and get rid of these parts here and of this state because we'll have to change the entire logic of our PostsList component and how it works soon. So for the moment, if I save it like this. If I reload, we show that list of posts, and we don't have to duplicate header anymore. But, of course, this button here still won't work. I'll get back to this soon. What I wanna do first though is I also wanna refactor the NewPost component and also move that along with its styles file into the routes folder because this is also loaded as a route. So here, we have this new post component here, and with it being moved here, this button still doesn't work. But if for the moment I manually enter /create post in the URL, this gets loaded. However, not as a modal overlay above my PostsList, this does not work. As you can see, I have my PostsList here, but the NewPost page was not loaded as an overlay and that's therefore some more refactoring which we have to perform. This NewPost component should still be loaded as a modal and therefore, inside of the NewPost component, I'll use this modal component. Previously, I used it here in PostsList, but there, I'll soon get rid of it. So instead inside the new post component, I want to use this modal component as a wrapper around this form. And for that you have to import this modal component from going up one level components modal like this so that this still gets rendered as a modal. And in the PostsList component, I wanna clean up this component. This should no longer be responsible for also adding NewPosts, instead that will soon be taken care of instead of the NewPost component. So in the PostsList component, we can get rid of that code where we render the NewPost component in a modal. We can therefore get rid of this isPosting and also of the onStopPosting props, get rid of these two imports which we don't need anymore. And also theoretically here of that addPostHandler function, but I'll keep it for the moment because I will soon need that code again. But with that, if we save this, if I now go to create-post, it now opens as an overlay. However, not as an overlay above my PostsList. To make that work, we actually have to turn this post component into a layout component itself, because whilst it does not provide some sidebar or main navigation, it still should provide an element that's also available in the NewPost component. And that would be the list of posts. So I'll actually add a children prop here to the app component, which was actually renamed to posts. So I'll rename it here as well in the import and when I use it. And then here in this array of child components, I wanna render create post as a child component. So this new post component is now a child route of the posts route. So we have some nested layouts here, but due to this setup, we'll be able to render this NewPost modal as an overlay to this list of posts. For that, we just have to make sure that we also add an outlet here, and this can again be done by importing outlet from React Router DOM just as we did it before, and then we could add it here above this main section. So now posts is technically also a layout route you could say, and we got these nested routes here to achieve this look where if I now open create posts, this is open as an overlay above my list of posts. At the moment that list of posts gets reloaded because I manually entered the URL and therefore, loaded this page as a brand new page just as if I clicked the reload button. But you see it now is rendered with exactly the look I wanna have, which is that we have this as an overlay, though at the moment, closing this of course does not really work and we also can't open it by clicking New Post. So that's something we should also change. So how can we make sure that clicking New Post opens this New Post modal? Well, we need to create a link between these two different routes in the end. And for that we can go to the MainHeader component, which is where I have this button, we now must edit this component a little bit. We must replace this button with a link to this /create-post route, that's in the end what we want to do. So for that, we could replace button with an anchor element, which is the right element for creating a link and get rid of the onClick handler and get rid of that prop, which we don't support anymore. And instead add the ref attribute here and point at create-post. If we do that and save this, the styling is a bit off, we get this underlying effect but we can ignore that. If I click this, it seems to work, but I say it seems to work because actually if you watch this refresh icon, if I click New Post, you see it briefly changed to a cross, which means that technically a brand new request was sent to the server serving this React app and we technically downloaded the entire React app again and started it as a new instance of that app, you could say. So it's just as if I manually pressed this refresh button. This works, but it means that we leave the single page application just to load it again, which means any global state would be lost. And we of course also unnecessarily download and execute all the JavaScript code again, which is not great for performance. For that reason, we wanna stay in that single application world and just make sure that the URL changes and a new component gets loaded without sending a new request to the server serving the React app. And this is of course a common use case, and therefore, we can import the link component from React Router DOM. We should use this link component instead of the anchor element. Under the hood this renders an anchor element, but it prevents the browser's default of sending a request. This link component doesn't take the ref attribute, but instead the two property. But we can and should then still target create post. I'll also now briefly go to my MainHeader module CSS file, and they are on button. I'll simply set text decoration to none to get rid of the underlining, but the more important part is the usage of link. With that, if we save this and we go back to slash nothing and I click New Post, you now see it did not reload the page. And you can also tell that it didn't do that by the fact that if I load this, you have this list of posts and if I click here, you see in the background, it's not re-fetched again. Instead we're still on the same single page application. And that's, of course, the user experience we wanna offer. It's way better than the other experience we had before. Of course, we now also wanna make sure that we close this modal if we click the backdrop or if we click the Cancel button. Also if we submit it, but submitting this and handing submission is something we'll handle later. Now to also navigate, when we click the backdrop of the modal, we can go to the modal component and there we can get rid of that on close prop because we can actually handle clicks inside of that modal component now. Assuming that we always use this modal to wrap a page with it, so to use it as a wrapper inside of a route and that we always wanna go back to another route if we click on the backdrop, but if that is our assumption, we can add a function here. The close handler, which will be assigned to this onClick event listener on this backdrop div. And in there, I know also wanna navigate, but now we have to navigate programmatically here because this is now not a link, but instead an action that's executed when we click a div. We could replace the div with a link, but here I'll stick to a div also to show you how programmatic navigation works because sometimes you must initiate navigation actions from inside code and this is how you can do it. You can import another feature, another function from React Router DOM for that, and that function is actually a hook. They use navigate hook, a hook provided by React Router DOM. In React, you don't just have to hooks that are built into React. Instead, you can also create your own hooks and you learn how to do that in my course as well. And therefore, third party packages like React Router DOM also can create and share hooks. Now useNavigate can be executed to get hold of a navigate function, which I store in a constant here. But this in the end holds a function, therefore, we can execute it as a function here in closeHandler, and then we pass the path to it to which we wanna navigate when it's executed. And we could navigate to slash nothing to make sure that if I click on the backdrop, I navigate back to the starting page. We could also make this more flexible and use a relative path and use two dots here, which works in the same way as two dots work in the terminal when using the CD command, you go up one level. It's the same here for routing. You can use this special relative path here to go up to the parent route. So to the route above this route that's currently active. This would make the modal a bit more dynamic. It's up to you what you want. Here, I'll use this approach. And therefore, if this is loaded as part of the /create-post route, we would go up to the parent route, which is this slash route here. So therefore now with that, if I save this all, we can still open and close the modal. We can also make sure that the cancel button closes the modal. For this, we can go to the new post component again, which is where we have this cancel button. And we could now also initiate programmatic navigation here again, but here in the end it makes more sense to render a link again. Therefore, we can again import the link component from React Router DOM, and then replace this button down there with this link. Get rid of the onClick event listener now, and therefore also actually get rid of the onCancel prop up here, because we're not using that prop anymore. And now we can go back to this link, add the two prop and tell React Router where to navigate to when this is clicked. And here, we could again use two dots to simply go up to the parent route, which is the same as adding a slash here as an absolute path in this case. It's up to you what you wanna do. Both works. So now with that styling is a bit off, but if I click Cancel, we now also close it. Now to fix the styling, you find an updated new post module CSS file attached, and you can simply grab the content of that and replace your NewPost module CSS content with it. If you do that, you will see that now styling looks better again. So that's how we can navigate between our different routes, and now we got almost the same behavior as before, but now with the advantage of having sharable URLs and with the routing being used for linking these different parts. And that's actually a big improvement over what we had before because it means that we can now share links to the different pages that make up this app. And of course, the more complex your React apps are, the more likely it is that you need such shareable links and that you want to use routing for loading different parts of the website. Now with routing added, we added another crucial feature to this application, a feature which is especially important in more complex web applications you might be building with React, and React Router, at least if you have version 6.4 or higher installed, also offers some amazing features that go beyond picking the right component for the right path. Instead, React Router when using version 6.4 or higher also helps with data fetching and data submission. And that's now the last part we're also going to explore in this crash course because of course here we are fetching data. In the post component, we have the PostsList component, and in there we are fetching data. We have to useEffect hook here where we load our posts and set our posts. We also have the code for ascending postData here, but that code isn't used at the moment anymore, and I'll get back to that later. But when it comes to fetching data, we could stick to use a fact. But when using React Router version 6.4 or higher, we have a more convenient way of doing so, because with that version, you can go to your route definitions to the route that needs data. So the posts route here, for example, and you can add a loader property to that route definition. Now the loader property expects to get a function as a value and React Router will execute that function whenever that route gets activated. So whenever it's about to render this element, that's when this function gets executed and you can therefore use this function to load and prepare any data that might be needed by this route component or any other component used as part of that route. So any nested component used inside of the post component, for example. Now, therefore, we could add the data fetching logic for sending that HTTP request here, but to keep this main JSX file lean, it's more common to go to your route component file. So in this case, the post JSX file and there export an extra function, which typically is called loader though the name is up to you. But loader is a common convention since this will be the function that will be assigned to that loader property in the route definition. Now that loader function here still executes on the client side. It's still code that executes in a browser and therefore in there, you can do whatever you wanna do that could be done anywhere else in this app as well. Here, I wanna fetch my posts, and therefore I'll go to the PostsList component and copy these two lines of code here. The state updating code does not matter here, because this loader function executes outside of the component and can't manipulate component state. You will still see how we then get the posts into the component a little bit later. So I cut the code for fetching data and back in Post JSX, I'll paste it into this loader function. Now since I use the await keyword here, we should add async in front of that function to unlock that keyword. And we can do that because this function which will be assigned to this loader property can be an async or a synchronous function. It may return a promise or it may not React Router does not care about it, but if it does return a promise, React Router will wait for that promise to resolve before it then renders this route component. So this element which you specified here, and therefore, here we can use async and then send our request to fetch all posts and extract the data. And then that's the important part, we can return the data that we wanna expose to the element that is rendered for the active route. So in this case, resData.posts, I returned that as part of this loader. And then in main JSX, we can import this loader by editing this import here, where we import the posts component function. And there we can also import this loader and I'll give it an alias since we might have more loaders from different routes and we don't wanna have name clashes. We could name this postLoader, but of course this name is up to you. So in the end, it's now this loader function here, which is assigned as a value for this loader property in this route definition. And therefore, React Router will execute this function and wait for the promise to resolve before it then renders this element. And the data we return here in this loader is actually exposed to this element. React Router will make sure that the data returned here can be accessed in this route element or in any nested component. So also PostsList, for example, that's what we can go to PostsList. And there, we can now import another hook from React Router DOM, and that would be the useLoaderData hook. Now this hook can be called inside of the component function. Like all hooks, it must only be used inside of component functions in the end. And that gives us the data that is returned by this loader that's assigned to this route, which is the route that is active when the PostsList component is rendered. So here, I get my posts in the end, because in my loader here, I'm returning the posts. So that's what I get here with help of useLoaderData. Therefore, we can get rid of that post state. We can also get rid of the isFetching state because the loading state of this route and this route component will be handled differently soon. And we can also get rid of this entire useEffect call here because we don't useEffect for data fetching anymore. Instead, we use this feature provided by React Router. We therefore should also remove these imports of useState and useEffect. And then down there in the code we no longer have, this isFetching condition, because we no longer have this isFetching state, so that should go away. And we also don't need to check for isFetching here anymore. I do however, still want to check for whether we have posts or not. And post is now simply coming from useLoaderData, which gives us the data returned by the loader that was called for this route, which is active at the moment. With that, if we save this, if I reload, you see nothing for a short period, and then it actually loads the page and shows us the posts, and we see nothing initially because now the behavior is that as long as the loader executes, this route element isn't rendered. So React Router waits for the loader to finish before it renders this element. And actually here this even means that nothing is rendered on the screen if we first navigate to this page. If I instead navigate to this page after closing this page, it actually executes this behind the scenes, and therefore, then we don't get stuck and have an empty page for a brief moment. But if we visit this page for the first time, we see nothing initially until everything has been loaded. Now this might not be the behavior you want, and React Router also gives you ways of showing pages earlier and not waiting for the loader to finish. And I do dive into more advanced React Router features that help you in such situations as well in the complete guide course, but it's a bit beyond the scope of this crash course. The important takeaway here simply is that this loader is executed before this element is rendered. And whilst this might not be ideal, in case of a slow backend as we have it here, it's a great solution for all cases where you don't have a slow backend. Because if I go back to my backend code and comment out this timeout here, so that we don't have this slow down on the backend anymore and I then restart this backend server, you now see that it loads pretty much instantly if I reload this page. And therefore, now we have a great user experience again, but we have way less code that must be written inside of the component since we're using this loader feature. And again, for situations with slow backends, they're also with be solutions. And therefore, you can handle all these scenarios with less code, which is of course great since it decreases the complexity of your app, and it means less work for you as a developer. So it's great that we can now load data with that loader feature. But what about submitting data? What about creating a new post? At the moment, this doesn't work, and of course it should work. And for that we can also leverage React Router. It's the NewPost component where we have this form in the end, and we got a bunch of code for getting the user input and for then preventing the default behavior off the browser and doing something with the data. Now what we could do is we could grab that code for ascending that data to the backend and cut it from addPostHandler here, and actually get rid of addPostHandler in PostsList, making this component even leaner, and instead added here in this NewPost component instead of calling onAddPost and onCancel. Instead of doing that, we could send that postData to the backend right from inside the NewPost component. And indeed this would work, but it's still a bunch of code we would have to write here, especially since we probably also wanna close the modal thereafter, which means that we then also have to add extra code for navigating to a different route programmatically, better and more elegant approach is to also use a special feature offered by React Router, because just as you can add loaders to your routes to load data before it gets activated and before the component gets rendered, you can add actions to routes. So to this route here, to create post route, we can add an action by setting the action property. And just like loader action wants a function as a value. This function however, will now be triggered when a form is submitted in that route, which means that here in the NewPost component, we could export such a action function, to again have that code close to the component to which it belongs. And then in here, we could add our code for sending that request like this. Now we still need to get the postData, but that's how we could get started. But how do we now get the data that's entered into the form by the user? Well, previously we had to manage our own state for that. Now when we embrace React Router, this all gets much leaner again. We can delete that state and delete these functions that updated the state. We can also delete this submitHandler, and therefore, also delete the useState import, and get rid of the onSubmit event listener on the form element and get rid of the onChange listeners on the inputs. So we already got rid of a lot of code here, and instead all we have to do here is add a name attribute to our inputs. So in this case to the textarea here, and then assign a name which we later wanna use for extracting and submitting our data. So, for example, here, my posts have a body and an author field here. And if I wanna stick to that to body and author, I could give my textarea here the name body and this here the name author, so that I already use the keys, which I wanna use for storing my data here on these inputs. But what's the idea behind this name attribute? Well, it's a default HTML attribute that can be added to form inputs and by default if a form is submitted, the browser will as mentioned earlier, generate a request and it will try to send it to the server that served that website, which would be wrong because that server that's serving that website doesn't have any code to handle this request with the form data on the backend because we have no backend code as part of this React app. But that's now where React Router comes in. We can import a special component from React Router, and that would be the form component with a capital F. And if we use that instead of the regular built-in form element, React Router will handle the form submission and it will prevent that browser default of sending a request, but it will still gather all the input data, still generate an object with that data for us. And that's the important part call the action that is assigned to the route which contains the form, the Form with the capital F. So therefore, now with this Form component being used, React Router will in the end make sure that this action here gets executed. And therefore, we cannot also import this action function which I'm exporting here in NewPost, import this from the NewPost component file here, the action, and maybe also give it an alias in case we had multiple actions from different routes to avoid clashes, that could be the NewPost action therefore, and assign that as a value for the action property down there like this. So that in the end, it's now this action function that will be executed by a React Router if this form here is submitted. Now one last thing I'll do here is I'll add the method prop here to this Form component and set it to post. Now it's important to understand that no actual post request will be sent anywhere because this is still all clients had code. But what React Router will do behind the scenes is it will generate a request object with that form data included in it, and it will give this request object a method which we could then use here on the action to find out which form was submitted when this action was triggered, in case, we had multiple forms that belong to the same route with the same action. And even without that, it's kind of a good idea to use the semantically correct HTTP work. And since we're creating a new post here, the post method makes sense because that's typically the HTTP method that is used for creating resources. So with that, no request is sent to the backend, instead this action will be executed. And here, you actually get some data argument. This is passed in automatically by React Router and that's not the data of the form. Instead that is an object which for example has a request property with that request object that's generated and built by React Router. So React Router calls this action function and passes this object that includes the request object that was generated to this action function. Therefore here, we can actually use object destructuring to get hold of that request object like this. And now this request object has a formData method. And when you execute that formData method, you get access to the data and code it in that form. So the data that was extracted by React Router when it analyzed that form and called that action. Now formData actually yields a promise. So we should turn this into async function so that we can use await. And then here, we got our formData object. And that is a rather complex object, it's not a plain key value store. Instead it's a object that, for example, has a get method which you could call to get the value provided for the body field, like this. That's how you could then extract the data that was provided by the user. Now an easier approach here is to instead create a postData constant and use the built-in object class and call from entries and pass this formData object to it. Under the hood, this will simply then create a basic key value object where you have a body key with some value and an author key with some value in our case here, since we have body and author as name values in this form. So that's how we can extract the formData with help of React Router. Again, all still happening on the client side here, and therefore, now we got the postData we need for sending that request. Here, we can also await this to wait for the request to be sent. We could also get the response and analyze the response, for example, to find out if something went wrong, but I'll not do that here. And instead now after sending this request, we can also call another function provided by React Router DOM, and that would be the redirect function. This is imported from React Router DOM, and you can call it in your action and loader functions to return the result of calling this function here. Now what redirect does is it generates a response object, which in the end is then returned by this action. And if you return such a response object, React Router will look into that object. And if it's a redirect response, which is the kind of response that is generated by calling redirect, React Router will simply move to that different route to which you're trying to redirect. So here, we could pass a path of slash here to make sure that after this action was called, we actually make React Router load a different route. The route with the path slash, which in this case is of course this route, so that we leave the create post route and we move to this route instead. That's how we can initialize this navigation action. Again, all performed by React Router here, there is no backend code involved here, we're just sending a request to the backend, but this code here all runs on the client side in the browser. But with that all added, if we save everything and we go back and go to the new post area and try to add a new post like this, you see I am redirected this new post shows up here. If a reload, it still shows up here. So it was indeed sent to the backend. We can also see it in post JSON there. And therefore, this proves that this action works the way it should and we're now using React Router for sending and for fetching data. And as a result, you can see that our components got much leaner. We don't have to manually keep track of what was entered. We don't have to manually handle the form submission and prevent the default, we have to do none of that, we instead embrace React Router for sending and getting data for navigation between pages. And that's why React Router is awesome also for simple demos like this one, but especially of course for more complex websites. Now with all that done, there's one last thing I wanna implement one last feature, and that is that I can click on one of these posts here. And if I do that, it simply opens as an overlay, just as new post. But with the details of that post which I clicked. To make that happen, we must add a new route first of all. And that should be a route nested into this post route since I want to have that same overlay effect as I do for a create post. So I'll add a new route definition here. And now the question is what should be the path? And the path in the end should be slash and then the idea of the post for which I wanna load the details. And that's really important, I need to have that ID included in the path so that once the route becomes active, I can take a look at the path, get the idea of the post for which I wanna load the details from there, and then load those details from the backend and display them on the screen. Therefore, we actually have different values for this path here. For one post, it could be this ID, and for another post, it would be this ID. Of course, we can't register all these routes here because we don't know in advance how many IDs will have and what the concrete values will be. Instead we add a placeholder by adding a colon here. And then any name of our choice like ID or postId, that's up to you. I'll pick just id. We can also add a slash here to make this an absolute path or omits the slash to make it a relative path, simply appended after the path of the parent route. We could have done the same thing for create post. That's up to you. Here, I'll stick to absolute paths, but that's not required. So that's how we set up a dynamic route as it's called, with a dynamic path parameter. Now we also need a new component that should be rendered when this route becomes active. And for that attached you find the post details component with its JSX file and its module CSS file. Now this component here renders simply some details about the post which was loaded. Here included in a modal, and also with some fallback content if no post was found for the ID that was provided. And I'm using useLoaderData to get hold of the post. So I'm expecting to use a loader for loading the post for that route here when it becomes active. So we'll add that loader function in just a second. As a first step, I instead wanna simply import this postDetails component from routes postDetails, and then assign it here as an element, postDetails like this. With that it's this component, the postDetails component that will be rendered on the screen if we visit slash and then any postId. However, as mentioned of course here, we need some loader data because I'm expecting to get my postData with help of a loader, and therefore, I'll export an async function called loader here in this newly added postDetails component. And back in main JSX, we can also import this loader and assign an alias. And that is why we use aliases by the way. Otherwise, we would have two loader functions here and that would be a name clash that is not allowed. So therefore here, I'll also assign an alias and name this postDetailsLoader, for example, and assign this to the loader property of this route definition down there. So with that, we also got a loader here. And now in that loader of the postDetails component, I wanna send a request to this backend route here where I also have such a placeholder, but that is Express.js has nothing to do with React Router, it's just a common way of solving such dynamic path segments. But in the end, we need to send a request to our backend domain /posts and then slash the id of the post which we wanna fetch. And therefore here, all again, use the fetch function, send my request to HTTP localhost 8080 /posts and then slash plus the id of the post for which this route was activated. Now, of course, that will be different IDs, so we need a way of getting the actual ID that was loaded for this exact time where this route was activated. And we can get that from a data object that's passed to loader just as action receives an object, which for example includes a request property with details about that request object that was generated by a React Router. The loader also receives an object, which also would've a request object, but which more importantly has a perams object. This by the way, also exists for action functions. And this perams object simply allows us to access the ID for this route here. And here I'm using.id, because I chose ID as a placeholder here in the route definition. If you chose something different here, like postId, you would have to use that same identifier here, like postId. This will give you the actual postId that's included in the URL when this route is visited. And therefore will send such a request to the backend to fetch the details for that post. Now here, we can await that to get our response. We can then get our response data by awaiting response.json as we're doing it for fetching all the posts, it's essentially the same code. And then here, I simply want a return resData.post, .post because my backend sense back an object with a post key that contains the post that was fetched or undefined if no post was found. But I handle that use case here in my component. So therefore, now we're returning the single post here, we're getting access to it here with useLoaderData in post details, and we have registered this loader for this details route. Now with that all added, we also must make sure that we can reach this route. And to achieve this, I'll go back to my PostsList component where I render my posts and the effort to the post component where I have the actual post. And here, I wanna wrap that with a link. So I'll import the link component again from React Router DOM, add it here, and wrap the content here with that link. And then set a two path here to the ID to which I wanna navigate. Now this again should be dynamic because different posts have different ideas. Hence, I expect to get the idea of my different posts as prop values here, just as offer and body are different for different posts. And then I set this two value here to a dynamic value, which is then my ID, generating a relative path to that ID. So it's simply appended after the currently active path. They should give us a link that leads to post with a specific ID, and to make sure it's styled properly, I'll go to post module CSS and add a short new style here, maybe below the post, exact position does matter where I'll target the anchor tag that's rendered by the link component and set text decoration to none. With that, we just have to make sure that a value for the ID is passed to post. So in PostsList where I render my posts, I'm now also setting the ID prop and I set it to post.id because my posts now have IDs since they're coming from the backend, and there an ID is added. We could also use that ID for the keynote, by the way, since it's a better, unique identification criteria than the body. But we have to set the ID prop here on post, so that there it can be used for the link. And with all that, these items are now clickable, and if we do click them, we view the details about a post, and we can click the backdrop to close this. So that's working as it should. And that's therefore it for this crash course, where we built this demo application, which allows us to create posts, view posts, and also load the details of a post with help of routing now. And along the way, you of course learned a lot about React. You learned all the essentials like working with props, components, state, and useEffect. And you learned how you can also add routing to support multi-page experiences while still being in a single page application. You learned how React Router can help with data loading and data submission. And by the way, as you might notice, this means that your component code got drastically easier. There's way less state management in there. Indeed here we have no state management at all anymore. And therefore, now at the end of this crash course, you got a solid set of skills, a solid foundation for working with React, for diving deeper into React with the official docs with my complete guide, or for diving into frameworks that build up on top of React like Next.js or Remix, which would allow you to build full stack applications with React instead of just front end applications. And therefore, I hope that this crash course was helpful to you, and I wish you all the best for your future work with React.