
This Apress imprint is published by the registered company APress Media, LLC, part of Springer Nature.
The registered company address is: 1 New York Plaza, New York, NY 10004, U.S.A.
Dedicated to my precious daughter, Ithal, and all her hilarious reactions
React is a JavaScript library for building user interfaces in a simple and efficient way. We stay close to this concept of React in this book. Basically, this book explains React in its simplest form. It’s designed to be digestible, with straightforward examples so that you can learn React by mastering it slowly. Using the most recommended and latest techniques, this book will teach you how to design React components the React way.
We’ll begin by gaining a basic understanding of the Web. Then we’ll see how React fits into the picture. The second chapter goes over modern JavaScript concepts to make sure you’re padded for learning React.
Reacting starts in Chapter 3, and we’ll talk about the ingredients behind React and make sure the basics are sound. During this chapter, you will learn about components, JSX, props, state, the Virtual Document Object Model (DOM), conditional rendering, and building a React app.
Chapter 4 shifts our attention to thinking in the React way and how to design React components. You will learn more about component design and interaction. You will see how a parent component interacts with a child and how sibling components interact. Based on all these concepts, you will build a multicomponent app. In Chapter 5, the book asks you to rethink. You will learn about potential design flaws in React and learn how to tackle them. Then, you will build a multi-view React app and learn about React Context.
As we move forward into Chapter 6, we will examine different ways to debug React apps. The Chrome DevTools, Visual Studio (VS) Code tools, and React DevTools will be discussed in depth. Throughout Chapter 7, you will learn how to style React apps. We will discuss SCSS, Cascading Style Sheets (CSS) modules, etc.
Hooks await you in Chapter 8. Here, we will explore the component lifecycle in detail. Each React Hook will be explained with examples. When you finish this chapter, I promise you’ll be a Hook master. The penultimate chapter will look at how React interacts with backend services. It will cover routing, API communication, authentication, and Redux. After discussing the impressive features of React 18 in the final chapter, we will draw a conclusion.
While reading this book, if you have any questions, you can contact me by leaving a comment at Just React Q&A (https://jrhn22.wordpress.com).
In terms of career opportunities, React is certainly one of the most in demand technology. According to most surveys, React is the most popular web framework/library in 2022. So what are you waiting for? Let us Just React! and enjoy this responsive ride with “React” together! Enjoy the read! Enjoy the learning! Just enjoy React!
First, I’d like to say thanks to my wonderful wife, Divya, for keeping me motivated and helping me through this writing process. Without her constant support, this book would not have been possible. Thanks to my adorable daughter, Ithal, for all her cute interruptions. Thanks to my mom for her endless support and care.
I’d like to thank my coordinating editor, Aditee Mirashi, for making my job easy by providing continuous support. My sincere thanks go out to the development editor, James Markham, the production editor Dulcy Chellappa, the production coordinator Krishnan R S, and the entire team at Apress and Springer Nature who worked on this book.
Frank W. Zammetti, the technical reviewer, deserves a big thank you for reviewing this book with such care and expertise. I was fortunate to have Frank review this book.

is a lead architect/developer for one of the largest financial firms in the world by day and an author/musician/techie/husband/father by night. He is the author of 13 books for Apress on various topics in software development, as well as several independent articles for various publications. He has served as a technical reviewer on several other books and has been a speaker at various technical conferences and meetups. Frank is a contributor to several open source projects and founder of a few as well. In addition to technical writing, his first novel, The Darkness Beyond the Light, is now available for free online. And if all that isn’t enough, Frank is also exceptionally good at finding the corner of furniture with his toes in the middle of the night. Like, seriously, why does this keep happening to Frank?!
As you browse the Web regularly, do you consider how reactive it is? How does it respond to you? Do you get reactions without refreshing your page? React is a JavaScript library that focuses on these reactions. This may explain its name, “React.”
In React, you can build individual user interface (UI) components. The concept of components is central to React. A component is a JavaScript class or function that can accept inputs and output a React element that describes how a section of the UI should appear. All the components you build together can make a complex UI. React renders this UI. We will discuss components throughout this book. This chapter will provide a solid foundation on the concept of the Web and how React fits in. By the end of this chapter, you will learn what React is, where you can use it, and the advantages of using it.
Before we get started with React, let’s look at how HyperText Markup Language (HTML) and JavaScript (JS) work together. HTML, Cascading Style Sheets (CSS), and JS are the three technologies that make up a web page. HTML forms the structure of the web page. CSS focuses on appearance. JS enables the interactions between the user and the page. If we take an example of a Facebook post, the Like button you see is made of HTML with CSS. When you click “Like,” it updates your like. Here you received a response from the web page. JS is the crazy guy behind the scenes who looked at your click and let you know that you already clicked this, by changing the “Like” icon to blue.
I will show you how HTML and JS work together in the client browser using Google Chrome as the browser. When you learn React, we will build on top of this basics. This is to ensure that you understand the basics well and how React works internally before you learn it’s features. This will help you make the right decisions while developing a React application.
Let us first check what is inside the body tag; div and p elements are examples of HTML tags.
An HTML element can have attributes, which include a name and a value. The name identifies what information a user wants to add, and the value defines what it means.
In the preceding code, for div we defined the value app for the attribute id. Using the style attribute, we defined the style of the element p. As you move through this book, you will see examples for different tags and attributes.
A content is the part that appears between a start and an end tag. In the preceding example, Just React is a content. An HTML element comprises the start tag, its attributes, the content, and the end tag. In the preceding example, the <p id="p1" style="color:red">Just React</p> is an element. The div element contains this p element as well. Therefore, p is the child element of the div element. The div contains two more child elements, which are the p element with id p2 and a button element.
Let us now look at the other wrapper elements we defined. The <!DOCTYPE html> tag tells the browser what version of HTML we are using. For older versions, we need to add a declaration to this tag. For HTML 5, we can just declare it like this. The <head> element defines data about the file. The <title> element defines the title of the document. You can see the title in the browser tab when you run the HTML on your browser. As the title is a data about the document, that is, a metadata, you need to put it inside <head>. The <body> element contains all the contents of the HTML document.
Put the code in Listing 1-1 into a notepad and save as Listing1-1.html. Go to the saved location, right-click, and open it in the browser. You can see the page displays the text Just React in red and the text 2022 in green. Whenever you open an HTML file saved on your local drive, the browser reads it but does not understand it. Then, how does the content get displayed eventually in the browser?

DOM tree
Next, the browser determines what styles need to apply to elements and creates another tree, called the CSS Object Model (CSSOM) tree. Then it combines the DOM and CSSOM trees to produce the render tree. The difference between a DOM tree and a render tree is that the render tree knows about the styles.
In contrast to the DOM tree, the render tree has information about the styles. Afterward, the browser computes the width, height, location, size, and position of each node in the render tree. Finally, it paints the elements on the screen. This allows us to view the content on the screen.
In an HTML file, we can add a reference to a JS code by using a script tag. If you refresh the browser screen and click the button, you see that the content has been changed to Welcome to Web and 1991. What exactly happened here? When the browser engine interpreted the HTML file, it also noticed the script tag and executed it.
Inside the script tag, we defined a function changeContent. A function is a set of code that performs a specific task. The function is invoked during the button click. We added a property onClick to the button element. The onClick is a JavaScript event. We will explore events in more detail in the next chapter, but for now, understand that when we add onClick=" changeContent()" to a button, the changeContent function gets executed when the button is clicked. In this function, we access both the p elements and change their content. Hence, the content is changed. The JavaScript here manipulated the DOM tree by accessing the p elements and changing their content. When parts of the DOM tree change, the browser recalculates the CSS, revalidates parts of the render tree, does a reflow (redoing the layout), and then repaints the screen. We made changes to the DOM tree twice in this function, to update content of each of the p elements.

HTML and JavaScript
The purpose of this section was to show you how HTML and JavaScript work together on a web page and how JS does DOM manipulation. In the next section, we will look at how plain JS compares to React.
In this section, we’ll compare how plain JavaScript (vanilla JS) and React work and what the major differences are.
So each time, the script traverses the DOM tree to find the specific node and updates the respective p element. After updating, the browser performs a reflow and repaints the updated parts, as explained in the last section. For every DOM update, the process repeats. For large-size applications with a huge DOM tree and more DOM updates, this can have a negative impact on performance.
React uses a concept called the Virtual DOM to work a bit differently. It creates two copies of the DOM in memory. When we change the DOM, it changes one copy of the DOM. Then, it compares that copy with the other copy to determine what has changed. This process is called diffing.
React then batches these changes and applies them to the real DOM in one shot. This way, it minimizes the reflow and repaint. This is how React improves performance.
Let’s look at the difference between the UI render processes in plain JavaScript and React next.
As we have seen in the previous section, we created the initial UI using HTML, and the browser displayed it. Then, the JavaScript got executed, and the browser repainted the screen with the updated UI.
So we defined the UI in our local drive file, and the browser built the UI based on these definitions. That’s how it displayed the content Just React in red color.
This component, App, returns JavaScript XML (JSX). JSX looks like HTML, but it is not. You will learn about JSX in detail in Chapter 3. For now, just understand it is an easy way of describing the UI you want to create. The syntax is like that of the HTML. JSX internally creates React elements.
In the browser, this described component is finally rendered to the root div element, which was initially loaded into the browser.
This is the current state of the component now. If we want to update the content of the p elements like we did in Listing 1-2 using JS, we need to update the state of the component.
Don’t worry about the code at this stage. Instead, just focus on what we are trying to achieve. All of the technical terms will be explained in greater detail when we go through each concept from Chapter 3 onward. The code will make sense when we get there.
The UI elements and the JavaScript code are encapsulated in a single component here. We defined an initial value for the content of p elements, which are Just React and 2022. These values are assigned to the variables statep1 and statep2. This variable values are then set as the content of the respective the p element. This is the current state of the p elements.
Next, look at the content inside the changeContent function. Inside the function, we set a new state to each of the p elements. This means, during button click, the content of the first p element changes to Welcome to Web and the second p element content changes to 1991. So here the state of the component changes. When the state is changed, React updates the Virtual DOM and applies the changes to the real DOM after the diffing process. If there are multiple state changes happening at once, React batches these state changes together before updating the DOM.

Plain JS – DOM update 1

Plain JS – DOM update 2

React – batch update to the real DOM via the Virtual DOM
So, in summary, React encapsulates UI sections as components. It controls the components using their state. React batches the state changes and applies them to the DOM after the diffing process. React manipulates the DOM much less, allowing it to improve performance. As a developer, all you have to worry about is building components and managing state. You don’t have to concern about how the UI gets applied to the browser. React loves to do that behind the scenes for you.
There is a common misconception that each DOM change by plain JS causes the browser to repaint the entire page. That’s not true. Modern browsers are smart enough to only update what needs to be updated. With plain JS, the browser is forced to recreate only parts of the DOM (the updated element and its children) during each update. And the reflow and repaint process follows for those parts. Here is where React brings in performance improvements by making use of the Virtual DOM and batching changes together.
There are many libraries and frameworks available that are built on top of JavaScript. A JavaScript library is a library of pre-written JavaScript code that allows for easier development of JavaScript-based applications. React is a JavaScript library, whereas Angular is a JavaScript framework. A framework comes with a structure and more features.
React focuses on the user interface (UI). React updates the real DOM only after the diffing process. This reduces direct manipulation and helps in improved performance. Even though Angular is a complete frontend framework, its DOM-based system can cause its apps to run slowly when dealing with many data requests. Angular provides more features and may be an overkill for smaller projects.
So, to keep things simple, Angular is a great framework and suitable for some applications. React may be well suitable for some other projects. As I mentioned earlier, React is much simpler to learn, and it is the most suitable tool for developing highly reactive web pages, like Facebook or Instagram. React is smaller in its size, faster and more popular among developers. Companies like Facebook, Instagram, PayPal, Netflix, Airbnb, etc. are making use of React as their core frontend technology. In the next section, let us go a little deeper into some use cases of React and how React fits into those.
When you go to a website, there will be three dominant entities involved in the content display: you, the browser, and the server. You make a request to the browser; the browser sends the request to the server and comes back with a response. There are two kinds of applications: single-page and multi-page. In a single-page application (SPA), the browser gets only one page from the server. So, when you as the user make a request to the browser again and again, the browser responds to you by changing certain parts of the single page. In this process, the browser does not reload any new page from the server. The browser takes only updated instructions from the server and does the rendering by itself. A single-page application interacts with the user by dynamically rewriting the current web page with new data from the web server, instead of the default method of a web browser loading entire new pages.

Multi-page application

Single-page application
An SPA reacts much faster. It is the JavaScript that is doing the entire job. There are no round trips to the server. It loads a single HTML page from the server and then responds to the user by rewriting the current page. Have a go on websites like Airbnb, Twitter, Netflix, etc. and see how they respond to you.
Do only SPAs use React? Not necessarily. You can even use React in MPAs. Basically, you can use React for two purposes. One is to build SPAs, where React controls the entire UI after the browser loaded the single page from the server. The other purpose is to control parts or widgets of a page in MPAs. In SPAs, when you switch between pages, React can control that behavior. Even though you may feel you are navigating to a different page, only one page gets updated behind the scenes.
This section aimed to give you an understanding of where to use React on a high level. You also learned the difference between SPAs and MPAs. We will develop both types of applications in this book.
The final code at the end of each chapter is available in the respective chapter section in the repository. You can access the repository via the book’s product page, https://github.com/Apress/Just_React. All the listings mentioned in this chapter are located under Chapter 1 ➤ Listings.
This chapter threw some light on where React fits into web development. We started with understanding how HTML and JavaScript work together to display a web page. We discussed the DOM and how JS manipulates the DOM to make a page reactive. I did a comparison between plain JavaScript and React to make you understand what exactly React is and what it is built for. Then we went to compare React with Angular, again to make you understand where React stands against other frameworks and libraries. To conclude, I described the difference between SPAs and MPAs and how each of these types of applications works in a browser. Again, this was to illustrate how React can work with each of these kinds of applications.
To sum up, the goal of this small chapter was to make you understand where you can use React and why to use it. In the next chapter, we will go a little deeper into modern JavaScript. This is essential to provide you the base on learning React. Chapters 1 and 2 give you the basics so you know what happens internally when you type in React code. If you are already much familiar with JavaScript and its modern features, then feel free not to react to Chapter 2 and just go straight into Chapter 3. I would recommend that you master plain JS before you start “React”! The goal of Chapter 2 is to help you with that.
Once upon a time, programmers used JavaScript (JS) only to add interactive features to web pages. Those days are long gone. Today, JavaScript is even used to develop games. JavaScript is without a doubt the most popular programming language in the world.
In our first chapter, I emphasized the importance of learning JS before working on React. In a few pages, this chapter will help you gain a basic understanding of JS. I do not mean this chapter to cover every JS concept but to equip you with the knowledge before you move on to React.
This chapter introduces Visual Studio Code (VS Code) as a code editor. The chapter focuses on the basics and ECMAScript 2015 (ES6) and above features of JS. ECMAScript is a specification, and JavaScript is a programming language that adheres to this specification. ECMA is an organization responsible for defining standards and maintaining these specifications. ES6 and above versions are the latest of these specifications.
In this chapter, we’ll cover most JavaScript concepts to familiarize you with the language before we move on to React. You may skip the sections you already familiar with.

Installing an extension in VS Code
By using this extension, you will view your code in the browser without having to copy and paste the link into the browser. You will see the changes automatically in the browser without having to refresh the page.
Once you saved the file, click the “Open Folder” button on the left-hand side of Explorer. Open the folder in which you saved the preceding HTML file. A prompt will open, and it will ask you, “Do you trust the authors of the file in this folder?” Click the checkbox to trust all files and then click “Yes, I trust the authors.” Now, you can view all the files of the folder on the left-hand side of Explorer.

View HTML in the browser
The HTML file opens in the browser with a URL similar to http://127.0.0.1:5500/Listing%202-1.html. You can view the current date and time in the browser.
In this simple script, we created a div element and assigned a content to it. We accessed the root div using its id attribute and appended the div to the root div.
As you may have observed, we added the script tag below the HTML element. This is to ensure that the browser loads the parent div first before we do the append operation in JS. If we place the script tag above, the browser will wait for the JS to load before it displays the existing HTML content. You should know the loading of JS depends on where you place the script tag. Usually, it would be best to put the script tag below the current HTML. However, there are scenarios where we put the script tag above or inside the <head> tag.
In the preceding example, we updated the contents of the HTML using JS. We executed the HTML in the browser. This was a simple example to show how JS interacts with HTML elements. In the next section, let us look at some basic JS concepts.
Each of the code blocks mentioned throughout this chapter is available in the Chapter 2 folder in the GitHub repository. You can refer to it via the book's product page, https://github.com/Apress/Just_React.
In Listing 2-1, you used the const keyword to declare the childDiv variable. What does this mean? You created an element and stored its value in a variable called childDiv. You used this value in the second and third lines. So a variable is a container where you can store values to be used later. For instance, in our example, the variable childDiv is holding the reference to an HTML element object. Then, you used that variable to set a text content to it and then to append it to the parent element.
We must create a variable before we can use it. The const keyword does that, and this is what we call the declaration of a variable. In modern JS, we use let and const to declare a variable. Let us identify the difference between these two keywords.
You can run the code samples in this chapter using jsfiddle.net.
This code works fine. The second line overrides the value you assigned in the first line. In the first line, we are initializing the variable bookname along with its declaration. Declaring a variable means we are creating a variable. Initialization means you are assigning an initial value to a variable at the time of its declaration. In the second line, we are assigning a new value to the variable bookname.
You will get an error in the second line, saying that we already declared the variable bookname. You must assign a value to a const variable at the time of declaration, and you cannot change it afterward like you did with let.
An object contains properties. Each property has a key and a value. In the preceding example, the object book has three properties. We define each property as a key-value pair. For example, bookname: "Just React" is a property of the object. bookname is the key, and Just React is the value of the specified property. An object can contain properties of any type. The properties of the object in this example are of both string and number types.
This will give you the value Apress.
const always is the better choice if you will not need to change the value of the variable later. Use let only if necessary.
To comment on a single line or multiple lines of code in JS, we can enclose the comment text with /* and */. Alternatively, we can comment on a single line by using two slashes. Comments are not an executable code; they just enable you to recall code later and help others understand your code.
In the previous sections, you learned about different data types in JS such as number, string, Boolean, object, and array. We call objects and arrays as reference types, while we call other data types as primitive types.
Now the bookName variable has a new value, Just JS. However, this will not have any effect on the variable newBookName. newBookName will still have the value Just React. It means that the variable newBookName just copies a value from the variable bookName and its existence is independent of bookName. Let us check this in jsfiddle. We will make use of jsfiddle in this section to test JS code.
Go to https://jsfiddle.net/. You don’t have to sign up. You can just start coding straight away. However, if you sign up and log in, you can save the work too.

Value types (Steps: 1, copy code to the JS box; 2, run the code; 3, see the console logs)

Reference types
Note that the value of year has been updated to 2023. You updated the year property of the book object, and the year property of the nextBook object was also updated. This confirms that just the reference was copied when you copied the book object. Whenever you update a property value, it updates the value in memory. It does not matter from where the value is referenced; the updated value always appears from memory. This also holds true for array elements.
In this example, you created the nextBook object by using the spread operator (...) as before. Then, we added a new property, publisher, to it.
While you work on React projects, you may find the spread operator very useful.
There are few values considered as falsy in JavaScript. When these values evaluate, they evaluate to the Boolean value false. The values false, 0, -0, "", null, undefined, and NaN are considered falsy. All other values will evaluate to true. These are called truthy.
Similarly, if(!isTravelResumed) is equivalent to if(isTravelResumed === false).
Let’s look at loops next.
In this for loop, we initialize the variable i with a value of 0. In the next line, the exit condition i< yearArray.length is evaluated. The console log inside the loop is executed because 0 is less than the length of the array. Next, the update expression i++ is executed, and it will increase the value of i to 1. Then, the process repeats until the value of i is not less than the array length. The loop ends the execution there.
The for/in loop is similar to the for loop. The difference is that it does not have the counting logic (i++) and the exit condition (i< yearArray.length). The for/in loop does not guarantee you the order in which the data is accessed. In this example, 2018 may get logged before 2021.
Here, hello JS gets logged into the console five times.
There are many other ways in JS to loop over a collection, such as an array or an object. We will get into use cases of this while doing projects in React in the upcoming chapters. This section was just an overview of conditionals and loops in JS.
As with most programming languages, JS has functions. A function is a set of code that performs a specific task. You can call a function as many times as necessary within your code using a single line of code. This avoids having to write the same set of code in multiple places.
In JS, you can use built-in browser functions or create your own custom functions. As the name shows, built-in functions are pre-built, and all you need to do is call them when you need them. You build custom functions from scratch in your code.

Swap case function
Here, the swapCase function converts the case of each character to its opposite case. Let’s examine each element of the code line by line. Here we have three elements: an input element, a button, and a span element. You can enter a text value in the input element. The button element calls the function swapCase. We added a property onClick to the button element. The onClick is a JavaScript event. We will explore events in the following section, but for now, understand that if we add onClick="swapCase()" to a button, the swapCase function gets executed during the button click.
Finally, the span element displays the converted text.
Now the array variable characters will have the value ['R','e','a','c','t']. In the next line, we use two built-in functions, toLowerCase and toUpperCase. toLowerCase converts the character to lowercase, and toUpperCase converts it to uppercase. We iterate over each character using a method called map(). map() is a built-in JS method that allows you to iterate over an array and change its elements using a function. A JS method is a property of an object that contains a function definition.
The function checks the case of the character and returns its opposite case. This happens for each character from the array. This is the capability of the map() method. The result of one execution is passed to the same function again and again.
By now, the variable changedCharacters will have the value ['r,'E','A','C','T']. The function will initially return ['r,'e','a','c','t'] by changing the first character, and the function will get called again with the result as the parameter. In the second execution, the result will be ['r,'E','a','c','t']. Finally, the result will be ['r,'E','A','C','T'] after all the characters are swapped.
This explains the complete code. This gives you an understanding of custom functions, built-in functions, and methods. We will go deeper into some methods and features of JS in the following sections.
Prior to that, let me explain how we swapped characters using the map() function in little more detail. For that, we need to know a few more things about functions.
And then we can pass this reference for other functions to use. This way, we can pass the variable reference of the preceding function to the map() function in the preceding example:
const changedCharacters = characters.map(swap);
In Listing 2-2, we added an event listener. What exactly are these events? In this section, we will dig into that.
Events are actions that get fired inside the browser, most commonly through user interactions, though not always. We can attach an event to a specific element, like an HTML element, or to the entire browser window. In Listing 2-2, we attached an event to a button element. The event gets fired once the user clicks the button. In the same way, you can attach events to various actions, such as when a user closes their browser window, when a user loads a web page, or when a user submits an HTML form.
The onClick event in JS allows you to execute a function when you click an element. Refer to Listing 2-2, under the function section, where you called the swapCase function at the onClick event.
The setTimeout function can attach an event to a browser window. The setTimeout creates a timing event that gets fired after a specified number of milliseconds. This timing event is attached to the browser window.
Arrow functions are functions having this kind of syntax. Arrow functions represent regular functions differently.
You can run Listing 2-2 now with the replaced line. It will work just like before. So this is another way of creating functions in modern JavaScript.
The major advantage with arrow functions is related to the use of the this keyword in callback functions, when we use map(), setTimeout(), etc.
When you use the this keyword, it usually gets you a value based on the context in which the function is called. this in a regular function always refers to the context of the function being called. However, in the arrow function, this has nothing to do with the caller of the function. It refers to the scope where the function (the enclosing context) is present. Let me explain this with the help of the following example. Refer to Listing 2-3.

this keyword in a regular callback function (Steps: 1, copy code to the JS box; 2, run the code; 3, see the console logs)
Let us see why this happened. We defined the year inside the printYear function. Initially logging to the console was done within the function printYear. So it can access the value of year using the this keyword.
The second time, logging was done inside the setTimeout function, not the printYear function. That means console log is not called within the context of where the year is defined. Therefore, this.year logged as undefined.

this keyword in an arrow function (Steps: 1, copy code to the JS box; 2, run the code; 3, see the console logs)
It logs the year value as 2022 both times now. Refer to Figure 2-7. What does the arrow function do differently here?
The arrow function only cares about where it is defined, not where it is called from. The setTimeout function calls the console log where we accessed this.year. We defined this function within the printYear function. We also declared the variable year within the same function where the setTimeout function was declared. Therefore, the setTimeout function can access the variable year. This is known as lexical scoping in JS.
Arrow functions are only concerned with the lexical scope, not with the context from which they are called. As a result, when we declare setTimeOut as an arrow function, it can access the year through this.year.
This behavior makes arrow functions very useful for callback functions such as when we use map(). This will be handy while learning React, where we will use a lot of callback functions.
In simple terms, a JS module is a file. We have seen HTML with JS embedded in it using a script tag. Instead, we can separate the JS into a file. HTML pages can refer to the saved JS through a directive called import. In the same way, if you have a complex JS application, you can break it up into several JS files. We can import content from one file to another by importing the module from file 1 to file 2. To import a module, say A.js to B.js, the A.js should contain the export keyword, and the B.js should use the import directive.
We will split our Listing 2-1.html into one HTML file and two JS files and see how they can work together. Create a JS folder in the Code folder that we created earlier.

VS Code Explorer
In swapCase.js, the function swapCase gets the value of the input field. It splits it into characters and calls the convertCase function from the convertCase module. Note that we imported the convertCase module using the import keyword.
We then join the converted characters in the array in the next step and then place them into the output element. By splitting JS into two modules, we achieve the same functionality. Now, let’s see how we can refer to the modules in the HTML file.
Here, we introduced a script tag and referenced an external JS module. Before moving on to the details of referencing an external JS module, let us look at how we can reference a plain JS file in an HTML.
So, whenever you click the button, it will invoke the swapCase function. Note that the script tag must have the property type with the value module. This is essential for the browser to load the module. Because the swapCase module imports the convertCase module in it, we don’t need to include that module in the HTML file.
Most of the modern browsers support JS modules. However, note that some browsers or older browser versions may not support this.
By executing the HTML in a browser, you will see the same functionality we achieved with the code in Listing 2-2.html. Our code is much cleaner now compared with Listing 2-2.html. We arranged the code into one HTML file and two JS modules. The module-based system is vital when working on JS projects as it will also assist you when coding with React, using components.
In the programming world, object-oriented programming (OOP) is a very common term. We did not initially associate JS with object-oriented programming. We heard the term OOP associated more with server-side programming with languages such as C# and Java at first. Certainly, you know now the JS is no longer the JS we have known before. In this section, we will look at a key OOP concept called subclassing.
This section aims to familiarize you with JS classes and subclassing before you work with React. This scope of OOJS is much broader than this section.
We already talked about what an object is, what a property is, etc. In this section, let me explain to you the concept of a class. We create a class with the class keyword, and it can have properties and methods. Properties are variables attached to classes, while methods are functions attached to classes. We have already discussed variables and functions.
Our code defines two classes, Book and ReactBook. Both classes have properties and methods. For example, name is a property of the class ReactBook, and publisher is a property of the class Book. getPublisher is a method of the Book class. The class ReactBook inherits from the Book class using the extends keyword. This means the properties and methods of the Book class will be available to the objects of the ReactBook class as well.

Subclassing with JS
This concept is called subclassing. Here in this example, ReactBook is a subclass. A subclass inherits the properties and methods of a class. Also, it can modify the properties of the parent class. A real-world example is a tree and a branch. A branch inherits the features of a tree, but it can have additional features, such as additional fruits or leaves. It can change the property of a tree as well. For example, a tree has a total of 1000 leaves; a new branch can increase the total leaves to 1100.

Synchronous execution in JS
We printed both strings out on the console with no issues. As you can see, in synchronous execution, the code is executed line by line. The script logged Learning into the console first. Then it called the display function. The function display called another function getContent that returned the value React. Both strings therefore ended up logged to the console.

Asynchronous execution in JS
The second line logged undefined instead of React. The display function did not wait for the getContent function to return anything. Instead, it continued to execute. We call this asynchronous execution.
It may be necessary to use web Application Programming Interface (API) calls to get some information in real-time projects. An API call is a call to the server, and it may take a few seconds or more to receive the information from the server. In the preceding example, setTimeout() was used to simulate the delay that can occur when calling a server-based API. It executes and creates a timer in the browser’s web API component.

Asynchronous execution with Async/await in JS
So now we have the desired result. The second line logged React, not undefined like before. The display function waited for the getContent function to complete its execution.
A Promise is an object that represents a proxy for a value that may become available at a later point in time. When we wrap a function inside a Promise object, the function will not return a value initially. Instead, the function will return a promise to provide the value in the future. So, initially, the value of the Promise object will be in the pending state.
When the function gets executed successfully, the Promise object’s state becomes fulfilled. If the function fails, the Promise object’s state becomes rejected. So the state of the Promise can go from pending to fulfilled or rejected.
When the state of the Promise object becomes fulfilled, resolve() will get called, and the value will be returned to the caller function, which is the display function here. If the state of the Promise becomes rejected, the reject() method will get called, and the error object will be returned to the caller. We didn’t define reject() in this example as there is almost no chance of an error since it returns just a string.
When we add an await keyword in front of the function call, it makes the rest of the code wait until a value is returned. So here, the second line console.log(what) waits until the variable what gets a value. Once the Promise is resolved, the getContent function returns the value, and the variable what will have the value React.
Note that we marked the function display with an async keyword. If we want to use await, the execution context must be marked as async. Since we use await inside the display function, we need to mark that function as async. Basically, async makes a function capable of using await.
In modern JS, we can make use of template literals. Template literals are literals delimited with backticks (`). Template literals are enclosed by backticks (` `) instead of double or single quotes.

Template literals(Steps: 1, copy code to the JS box; 2, run the code; 3, see the console logs)
Template literals are a very helpful feature while building React projects.
The aim of this chapter was to make you familiar with JavaScript. We started with basics and learned how to use JS in an HTML page. You learned about variables, functions, and arrow functions. We discussed conditionals, loops, and events. You learned how to import and export JS files using modules. We dealt with reference types and the spread operator. Last but not least, you learned one of the most important aspects of modern JS, asynchronous programming. We talked about promises and the Async/await syntax. Finally, we concluded the chapter with an overview of template literals.
The chapter focused to help you learn or refresh your knowledge on modern JavaScript and made you comfortable with the language before moving on to React. However, mastering JS is much beyond this chapter. You will need to do real-world projects and do more practice to master JS. But you are all set to start Reacting by refreshing/learning concepts discussed in this chapter. We will start with React in the next chapter. Get ready to React!
The focus of this chapter is to get you started with the React journey. The primary goal of this chapter is to teach you about the setup of React projects and the fundamental concepts of React.
Our first step will be to set up a development environment for React. Next, you will create your first project by setting up all the configurations yourself. We will build a React application from scratch to learn how React works behind the scenes. During this process, I will introduce you to Babel and Webpack. Following that, we will proceed to create a React application using a tool, create-react-app.
We will discuss components and JavaScript Extensible Markup Language (JSX). You will learn about the concepts of the Virtual DOM, props, and state. I will explain these concepts with the help of an example application. You will create a simple student enrolment form. You will learn about how components can interact with each other.
The chapter will take you the exciting world of Components, JSX, prop, state, etc. by using an example project and will serve as a foundation for learning React. Be sure to grasp the concepts and basics before leaving each section. At the end of this chapter, you will be in a good position to experiment and learn distinct features of React. Let us start by building a software environment.

VS Code terminal
In this book, I am using Node 16.13.0. I would recommend using the same version to avoid any issue while running the code. However, you are free to use the latest LTS version that is available while you are building new projects. The direct link to the page for downloading the version 16.13.0 is https://nodejs.org/dist/v16.13.0/. On this page, click the file link according to your operating system. For example, for a Windows x64 machine, click node-v16.13.0-x64.msi and it will get downloaded.
You can now start creating your first React project. The easiest way to create a React project is to use the command create-react-app. With this command, you can set up a frontend build pipeline without having to know how Babel or Webpack works. However, we will not use this command to create the first project. This is because we need to understand how React internally works. Hence, let’s tackle the hard path first. Afterward, we can create React projects using the amazing tool create-react-app.
As we move through the project creation process, it’s crucial that you understand each concept. Spend time understanding each step before moving on to the next one. You are doing all the setup yourself, and this enables you to comprehend how React works internally.
Each of the listings and projects used in this chapter is available in the Chapter 3 folder in the GitHub repository. You can refer to it via the book’s product page, https://github.com/Apress/Just_React.
Here we go. Open VS Code, click View from the top, and then select Terminal. This will open the terminal. Alternatively, you can press Ctrl+` to open the terminal. Then, set the directory on the location of your local drive where you would like the project to be. Then, follow the following steps.
Step 1: Initialize the project.

Create package.json
So we created a file called package.json using the command npm init. You might ask, What is Node Package Manager (npm)? What is npm init? And what is package.json?
npm is a package management tool that contains code packages. You have learned about modules in Chapter 2. A code package is similar to that. You can package a project and publish it to npm as a Node.js module. Other projects can then reference this package by installing it as a dependency. We can install these via the command line. You need to install Node.js to use npm. We already installed Node.js during the environment setup. NPM got installed as part of this Node installation process. A package.json contains information about a project, such as its name, version, description, etc. With the package.json you just created, you can see all this information. The information is in JSON format, with key/value pairs. The values are all set to default for now. Refer to Listing 3-1.
There is a different process to package and publish a project. We are not discussing that here. Here, we are talking about how to install an NPM package to our project.
The init command is a short-hand way of saying to initialize. So what we did here is to initialize the project using npm. The result is the package.json file, which contains the information about our project.
Let us keep the project folder open. In VS Code, click Open Folder on the left-hand side of Explorer and open the folder location in which you ran the command and created package.json. I created it inside the folder code.
Step 2: Install react and react-dom.
The next step is to install two dependency packages, which are react and react-dom. The react and react-dom are npm packages that you will need for your React app. The react package is the React library itself. It is the library your code will depend on to produce the HTML, CSS, and JS that will run in a browser. It is the actual React library that helps you build amazing user interfaces.
You use ReactDOM as the middleman that renders your React elements in the browser. The react-dom package helps you put your root HTML file into the browser using root.render(). First, we use the createRoot() method of ReactDOM to access the root node, and we call render(). Apart from createRoot() and render(), you won’t interact with ReactDOM directly from your code very much. Why do we need two packages? A loose coupling between React packages and the browser makes sense. We don’t use ReactDOM in mobile devices. We use React-Native for mobile development with React. React-Native acts as the middleman there. We use ReactDOM only in web apps.

Installing react and react-dom
As shown in Figure 3-3, the command successfully installed the packages. A folder node_modules got created with react and react-dom folders. Also, it created a JSON file, package-lock.json. The packages are now linked to the project.
During npm install, it autogenerated package-lock.json. It keeps track of the exact versions of all packages that are installed so that a product is 100% reproducible, even if the maintainers update the packages. package-lock.json contains information regarding the version of the React package and its dependencies. You can see that the React package depends on three packages: js-tokens, loose-envify, and scheduler. These packages were also installed when you ran the command. You can find the corresponding folders to these packages in the node_modules folder. The node_modules folder contains all the libraries downloaded via npm.
So far, we have initialized the project and installed npm packages that are required for running React code. If you look at package.json, you can see that it has react and react-dom also as dependencies.
Step 3: Create your index files.
In the index.js file, we imported react and react-dom packages. We used the createRoot and render methods of ReactDOM to render an h1 element inside the root div element.
Will the code work now? No, the browser cannot understand our code at this stage. Let’s continue on to the next step.
Step 4: Set up Webpack.
It is time to set up Webpack. As discussed before, in a React application, we will have a lot of code modules that we are referring to. So the total application package size can become huge. Webpack is a bundler that bundles all the JS files. It goes through the application package and creates a dependency graph to map all your modules. Depending on the graph, it creates a bundle.js file, which can then be inserted into an HTML file.
Let’s install Webpack packages and create a Webpack configuration file. We will further explore Webpack after that.
We use the webpack package to bundle all our code. The webpack-dev-server package allows us to execute the application in a local server during development. The webpack-cli package provides a set of commands we can use while setting up the project. The html-webpack-plugin is a Webpack plugin that is used to inject the bundled JS file into the HTML file. Using the --save-dev option ensures that it only added these packages as development dependencies. We do not require the preceding packages to run the application in production but for development.

Installing Webpack dependencies
Once we installed the Webpack packages, we need to set up a Webpack configuration file. Create a file called webpack.config.js under the root folder, which is the same directory where the package.json sits. Then, copy the code from Listing 3-4.
You can run a command, touch webpack.config.js, from the root directory to create this file. If you create by clicking the icon, from VS Code explorer, it may be created inside any child folders. If that happens, drag it on to the root.
During the first step, we defined two variables, path and HtmlWebpackPlugin. The requires function mapped the modules to the respective variables. The path variable holds the path module, and HtmlWebpackPlugin holds the html-webpack-plugin module. The path is a native Node JS module that allows us to concatenate file paths.
In the next line, we defined an entry for Webpack. This is where Webpack bundles and creates the dependency graph. We pointed the entry at the index.js file. We also defined mode as development. This is important as it tells Webpack to use its built-in optimizations. Next, we defined an output. This tells Webpack where to bundle the application. We specified it as a new folder dist under the root folder. The devServer key launches your local server by default without typing the URL. Having the key plugins ensures that the bundled JS gets injected into the index.html.
We now have set up bundling for your application so that we send only a single JS file to the browser. However, the browser will not understand your code because Webpack bundled it with JSX code plus ECMAScript 2015 (ES6) and above code. Before you bundle and send to a browser, you need to convert your code into something that a browser can understand. Let’s do that in the next step.
Step 5: Set up Babel.
This step is about setting up Babel. Babel is a JavaScript compiler. Babel converts ES6 and above code into a version of JS that runs in any browser, as well as JSX code. JSX is what we use for writing HTML in React. Your browser would not understand modern JS or JSX. You write your code in JSX and modern JS. Babel makes sure that the browser understands it.
We call Babel a transpiler. Transpiling is a special type of compiling where source code written in one language is transformed into another language that has a similar level of abstraction.
babel/core is the core Babel library, which does the transpiling. The babel/preset-env package is a preset that allows you to use modern JS without worrying about browser compatibility issues. The babel/preset-react package exactly does the same thing but for JSX code. And the babel-loader is a package that tells Webpack how to interpret and translate files before it does the bundling. The transformation occurs on a per-file basis before Webpack constructs the dependency graph.

Installing Babel
We currently have all the required packages. One thing is still missing, which is to add the Babel loader into the Webpack configuration. Let’s do that in the next step.
Step 6: Update Webpack to enable transpiling.
This code section sets a rule to use babel-loader. Also, we specify only JS files be transpiled, using the /\.?js$/ expression. We only need our code to be transpiled, not the node_modules folder. So we specify node_modules under the exclude section. In addition, we add the presets babel/preset-env and babel/preset-react, so that Babel transpiles both ES6+ syntax and JSX code.
Step 7: Build and run!
The script start will use the Webpack server and run the application locally. The build will create a bundle.

Running your app

React code executed on the local server
Remember, we have provided only one h1 element with this content. We can change the index.html or index.js code while the application is running, to include more content. The browser page will update automatically and display our updated content without needing to refresh.
The code in the index.js may look a bit odd at this stage, especially the <h1>Just React</h1> part, as you are yet to learn how to code in React. For now, just understand that it is a way of adding a header to display in the browser. This will make sense when I explain components and JSX in the upcoming sections.
Congratulations! You have just developed your first React application, the hard way. And you did it all by yourself! As mentioned earlier, the whole point of this exercise was to help you understand how a React application works internally.
From now on, you can just use the create-react-app command to create everything for you. We discuss that next.
To stop execution from the VS Code terminal, just press Ctrl+C on the keyboard and press Y for the prompt in the terminal. You can use the cls command to clean up the console. To create a folder, use the md command. To navigate to the folder, use the cd command.
The create-react-app command is a toolchain that enables you to create a React app without worrying about the configuration. Let’s create a React project using this tool.
The Node Package Execute (npx) is an npm package runner you can use to run any package from the NPM registry without even installing it. The npx comes with the npm when you install Node.js. The last parameter just-react is the name of our project.

create-react-app
As you can see, several JS files got created for you, such as package.json, package-lock.json, node_modules, etc. Move to your project folder using the cd just-react command. If the files are not opened on the VS Code Explorer (left-hand side), click File from the top and then select Open Folder and then open the project folder that way. Next, run the command npm start. This will open the localhost page in your browser. It will display the React logo along with the text "Edit src/App.js and save to reload".
To run the commands, if the terminal is not visible in VS Code, you can click “View” from the top and then select Terminal.
Go to src ➤ App.js file. Update some contents inside the file. Say you can update the “Learn React” text to “Just React”. Keep the browser open side by side. You can see the browser refreshes automatically with the new content.
Let’s see how this rendering worked.
You can see that the index.js renders the App component, which subsequently loads the content in App.js in the browser. As you can see, it already imported all the required packages in the components. Everything is pre-built for you by the create-react-app tool. You just need to build your own components on top of this.
How to create a new React project with create-react-app.
The tool create-react-app configured everything for you, including project initialization, file creation, package import, Webpack setup, Babel setup, etc.
index.html is the entry point of the application.
index.js loads the App component into the root element of index.html.
We defined the App component in the App.js file.
By modifying the App.js (App component), you can change the application content, and the browser automatically updates the page based on the changes.
To view the React version you are using, run the command npm ls react from the VS Code terminal. I am using React 18.1.0 for the examples in this book. When you run create-react-app, it will create the app by default in the latest version.
Let us continue by learning about components and JSX in the next section. We will build on top of the project we created in this section.
Components are building blocks of any React app. A React application’s user interface (UI) is a component, and it can comprise multiple components. A brick wall is a real-life example. Each brick here is a component that goes into the final component, the wall.
A component is a JavaScript class or function that takes an input optionally and returns a React element. That element describes how a portion of the UI should appear. The following example will help clarify this.
A component contains both UI elements and their associated functionality. Here, the App component combined the content of the div and button elements with the handleClick function.
In React, components enable reusability and modularity. Every component has a task, and it focuses on that. We have two types of components in React, class components, and function components (you can either use the term function component or functional component. Both denotes the same). When you progress through the chapter, you will learn about components in detail.
We learned in this section that a React app is built from components. Components are fundamental to a React app. It is important to break the app into components, each of which focuses on completing a single task. Components can optionally accept inputs and return React elements. Each component represents a part of the UI.
In the previous section, you saw that we returned the div and button elements in the App component. It looks like HTML, but it is not. It’s known as JavaScript XML (JSX). JSX is used by React to describe how the UI looks like. We can write the component code in plain JS, including the creation of HTML elements. JSX makes it easier by providing a visual feel like HTML.
JSX appears to be HTML, but it is a syntax coating on top of JavaScript. JSX allows you to write HTML in React and helps you create user interfaces easily.
We discussed a tool Babel in the section “How to React,” Step 5. Babel makes your browser understand your JSX.

Inspecting the component
As you can see, behind the scenes, Babel already converted our code into JavaScript code the browser understands. Instead of using JSX, if we have written your code like this, it would be harder to both write and maintain. JSX makes our React life easier.
In short, JSX is your visual-friendly coding option to construct the DOM in React. You will learn to write more complex JSX as and when we advance through sections and chapters. Next, let’s build a small app in React so that you can learn more about components, JSX, and the rendering process in React.
In this section, we will create an input form inside a component and then display it in the browser. We will accomplish this by adding on to the just-react app we created earlier.
Let’s create a component named EnrolmentForm and create a form for the users to provide student details.
Let’s go over the code line by line. As you can see, this is just a simple form with two inputs and a button. There is a reference to App.css on the top. Ignore it for now. We will add some code inside that for styling, at a later point in time.
The index.js already contains the logic to render the App component. But, if we need to see the contents of the enrolment form in the browser, we should update the App component to render the EnrolmentForm component. So let’s update the App.js, from where we left at Listing 3-7 in the previous section.
This makes it available to use in the current component, which is App. The ./EnrolmentForm is the path to EnrolmentForm.js.
Inside the div element, now we replaced the previous button element with the EnrolmentForm tag. Also, we removed the handleClick function, which we don’t require at this stage.

Form in a React component
We added the EnrolmentForm component to the root component, the App component. We have seen how the form looks in the browser. Note that the form elements we added inside the EnrolmentForm component are written in JSX. The JSX here describes how the form should look like. In the next section, let us add some styles to the form and learn how to implement some basic styling in React components.
We can style HTML elements by using Cascading Style Sheets (CSS) classes or by using inline styles. We can do the same with React elements. In this section, we will examine the basic styling of a component.
The preceding CSS code defines three classes. One is the enrolForm class. The other two are based on the input type. The second class enrolForm input[type=text] applies to all text fields inside a form that has the class enrolForm. Finally, the third class enrolForm input[type=submit] is the class used for all button elements inside a form if the form has the class enrolForm. As you may already know, CSS classes begin with the . symbol.

Styles in a React component
Now the form looks better since we applied all the styles defined in App.css.
With this section, you learned how to apply basic styling to a component by importing a CSS file and using the className keyword. In Chapter 6, we will dive deeper into styling in React and introduce you to dynamic styles, modules, etc.
We now have a simple form with some basic styling. You can enter data into both the input boxes and also click the button. In the next section, we’ll see how to capture and display your data after you click the button.
State is a plain JavaScript object used by React to represent information about the component’s current situation. A normal variable’s value will vanish when we exit the function, provided that we declared it in the function’s scope. However, in React, it preserves the state variable’s value.
Let’s see how we can make our form interactive. In the process, you will gain some understanding of the concept of state in React. Let’s create a label below the submit button and display a message on the label when the user clicks the button.
Now that we have a label, we want it to display the first name and last name as soon as the user enters those into the text boxes and clicks the submit button. To display these names, let’s add some logic to App.js.
For this scenario, what we would have done in plain JavaScript would be to get the values of the first name and last name from the input fields. We can achieve this by querying the elements by their id or another attribute. With React, we achieve this by managing the state.
In this example, we will use a React Hook called useState() to handle state. We will learn more about Hooks in Chapter 8. For now, just understand that the useState Hook is a function that allows you to declare state variables in the functional components.
When you pass the initial state to this function, it returns a variable with the current state value and another function to update that value. The first element holds the value, and the second element is the function, which can update the value of the first variable.
When a user enters the value and clicks outside of the first name input field, the setFirstName method called with event.target.value sets the entered value to the firstName variable. The event.target returns the element that triggered the event, which is the input field for the first name in this case. The event.target.value thus gives us the value, which is entered in the first name input box. So the setFirstName method sets the entered value to the firstName variable.
The setLastName method sets the entered value in the last name input field to the lastName variable. Therefore, the first and last name values will be saved to the respective state variables once the user has finished entering them in their respective input fields.
The function handleSubmit sets the message Welcome first name last name to the state variable welcomeMessage.
We use event.preventDefault( ) in order to avoid additional browser loads. A form submit event will invoke browser refresh, which is a native behavior of the submit button. We cancel this default behavior by adding event.preventDefault( ). Whenever you use a submit button, add this line at the end of the event function.
When the user enters their first name and last name and clicks the button, the function handleSubmit gets called. Then it sets the value to the welcomeMessage variable. The label appears with the message that contains the name.

State handling in a React component(Steps: 1, enter first and last names; 2, click the button; 3, the message appears)
In this example, we have seen how we can make an input form interactive by handling the state of the elements. It is noticeable that React and JavaScript differ significantly in how they handle input values and produce output.
Next, let’s examine how React code is being executed in the browser behind the scenes.

DOM tree of a React component
When parts of the DOM change, the browser recalculates the CSS, revalidates parts of the render tree, does a reflow (redoing the layout), and then repaints the screen.
We are accessing the DOM from our code in the preceding JS example to retrieve a label by its id and then write to it.
The JSX code we have written inside the return statement in the enrolment form component does not create any HTML elements or insert anything into the DOM. The JSX code is just a description of what we want the browser to display. We just described how the enrolment form should look through our JSX code. React then constructs a Virtual DOM tree of elements as per our JSX description. The Virtual DOM tree is a blueprint that exists in memory but is never rendered.
In the Virtual DOM, React builds an in-memory DOM tree, which is then rendered to the real DOM. During our school days, we might have written notes in a quick and dirty form during the lectures. Later, we merge these notes into a more readable form, after making all the required corrections. The Virtual DOM is something similar to these quick notes.

Virtual DOM
Props to React elements are like attributes to HTML elements. In React, props allow components to communicate. For example, we can send data from the App component to the EnrolmentForm component by using props.
Let us continue with the example of our EnrolmentForm component. As of now, we are displaying the form title as Student Details. Imagine the following scenario: We need a separate form title for undergraduates and postgraduates. The title should be UG Student Details for undergraduates and PG Student Details for postgraduates. To accomplish this, we need to pass a prop from the App component to the EnrolmentForm component.
Let’s examine the code in detail. After the required import statements, we initialized a state variable program with a default value UG.const [program, setProgram] = useState("UG");.
The event.target.value is UG if Undergraduate is selected and PG if Postgraduate is selected. So the value for program gets set accordingly.
If you see the app in the browser now, you will see the drop-down to select Undergraduate or Postgraduate. But the title will still say Student Details without specifying the default Undergraduate. Changing the drop-down also will not have any effect on the form title at this stage.
This is because we do not set the EnrolmentForm component to receive the prop, even though the App component passes the selected program as a prop. If you look at EnrolmentForm.js, the EnrolmentForm function has no parameters.

Components communicate using props
This simple example explained what a prop is and how components communicate using props.
In our example in the preceding section, we have seen how we passed data from the parent component (App) to the child component (EnrolmentForm). The parent component passed the prop down the tree. Because of this, the child component could access the information from the parent. What if we want to pass information up the tree, that is, from the child component (EnrolmentForm) to the parent App component? Let us look at that next.
This makes the data available in the parent component.
This way, the parent component can pass one or more functions to the child component. The child component can then use these functions to pass data and update the parent component’s state. Let’s see this in detail with our enrolment form project.
Assume that we have 100 seats for each program. Consider that the form we created is for internal use, where the staff users enter the students’ information. As soon as the staff submits a new student’s information, we need to subtract one seat from the total seats and display the remaining seats to the staff user.
The App component needs to display the remaining seats. This means whenever the user clicks the submit button on the EnrolmentForm component, we need to update the state in the parent component (App), so that it can display the correct number of seats.
In comparison to the previous code, that is, Listing 3-12, we made only four changes to App.js.
We have the seats displayed in the app with an initial value of 100, which you can see in the browser now. However, the number of seats will not update if we add a new student. In order to make that work, we need to update the state of seats in the App component when the user clicks the submit button on the EnrolmentForm component.
We added one line of code, props.setUpdatedSeats (props.currentSeats-1), to the handleSubmit function.

Updating the parent state using props(Steps: 1, enter first and last names; 2, click the button; 3, the seats are updated)
Here, we illustrated how to use props to update the state of the parent component by passing a function from the parent component and then invoking it from the child component. This example illustrated the two-way communication between components using props and state. Next, let’s discuss the difference between props and state.
Let us look at the difference between props and state, so that you know when to use props and when to use state.
Using state, you can store data within a component, and you can make the component interactive by updating the state. When you want to communicate with another component, props come into play. If you want to access the state of a component outside of that component, you need to use props to pass that state. Then, other components can access it. But if the component wants to change that state, then it needs to contact the component where the state is defined. Again, it can use a prop to do that communication.
The props are read-only, while the state can be updated. The props are used to pass data through the component tree from top to bottom. We can pass state as props, just like setUpdatedSeats in our example.
The more we move through the chapters, the more you will be familiar with the concepts of props and state and what the best practices are for using them.
In Chapter 2, we discussed conditional rendering in JavaScript. Conditional rendering means to render components based on conditions. Conditional rendering in React works the same way. You can use operators like if or the ternary operator to update the UI with the required elements based on the state.
Our example showed a logic for displaying seat numbers when enrolling a student. However, we did not differentiate between undergraduates and postgraduates. Imagine we would like to offer 60 undergraduate seats and 40 postgraduate seats. We need to display seats according to the selected program. Let’s see how we can achieve this using conditional rendering.
In the EnrolmentForm tag, we introduced a ternary operator for the currentSeats prop. If the program selected is UG, we pass ugSeats as the prop value. Otherwise, pgSeats is passed. This enables the EnrolmentForm component to receive the state of corresponding program seats and pass the corresponding argument to the function setUpdatedSeats from the handleSubmit function:

Conditional rendering in a component(Steps: 1, select a program; 2, enter details; 3, click the button; 4, the specified program seats are updated)
Thanks to conditional rendering, we achieved this functionality with minimal changes. Since the state is now passed conditionally, the corresponding state gets updated.
You can download or clone the entire project at the end of each chapter from the GitHub repository. The final code at the end of each chapter is available in the respective chapter section in the repository. You can access the repository via the book’s product page, https://github.com/Apress/Just_React. The just-react project is located under Chapter 3 ➤ Projects. After cloning, run npm install’ from the project folder to install all the required node modules before running the code. You can access all listings under Chapter 3 ➤ Listings folder. This book contains listings and code sections that have been tested and verified in VS Code, so there is almost no chance of an error occurring. However, if some code won't work, or functionality is unexpected, due to any unseen formatting issues, ensure that you take the corresponding component code or clone the entire project from GitHub.
This chapter got you started with React. We created a React application from scratch. We took the hard road and learned how React actually works. You learned about Babel and Webpack. And, finally, you created your first React app.
You created the second app much easier with the help of the outstanding tool create-react-app. Then, we discussed fundamental concepts of React using a simple student enrolment form. We discussed React components, JSX, props, state, and the Virtual DOM. Components are building blocks of a React application. Each component represents a task. A parent component can pass data to a child component through props. JSX describes how a component should look in the browser. The Virtual DOM is the in-memory representation of a component that is described by JSX. State is a JS object that represents the current state of the component. React updates any changes to the state of a React component to the Virtual DOM. React batches the state changes together and compares the Virtual DOM and pre-updated Virtual DOM. Then, it updates the browser DOM, and finally the browser displays the component to the user.
You learned about passing a function as a prop from a parent component to its child component. We discussed how this can update the state of the parent component by calling the function from the child component. Finally, we discussed conditional rendering in React. We illustrated it with a simple example.
We will unpack more into each of the concepts you learned in this chapter. In the next chapter, we will do more component interactions and will build more into our enrolment application by exploring events, props, state, and Hooks. In the process, you will start thinking in React!
In the previous chapter, you learned some basic concepts of React. We demonstrated these concepts with the help of a student enrolment form project. In this chapter, we will create a fully functional frontend application using the basic concepts of React.
This chapter will expand on the enrolment form project. We will discuss more about React concepts such as props and state, and I will introduce you to lifecycle events in React. Our project will comprise multiple components, and we will learn more about how to deal with the state between them. We will also look at React Hooks in more depth.
The focus of the first section would be to construct the enrolment form by applying some styling and refactoring. You will also gain an understanding of Fluent UI in this chapter. We will add more components to our application and make the components more cohesive. During the next few sections, we aim to design a list that stores and displays student details. We will incorporate the ability to add, delete, and edit items, allowing for more interaction between the form and list components.
This chapter builds a fully functional application by using the most recommended concepts of React. You will become adept at managing state between components by the end of this chapter.
Before we start with the chapter, you may want to install some extensions in Visual Studio Code (VS Code) for better development experience. You can install several extensions in VS Code. Go to the Extensions tab and type in the extension name and install it. I recommend at least installing Prettier, ESLint, ES7 React/Redux/GraphQL/React-Native snippets, VS Code React Refactor, and JS JSX Snippets. Another useful extension is JavaScript Booster. You can always type in React in the Extensions search tab, review details of the extensions, and, if they seem useful, install them. You can see the details of each extension at the bottom, when you select an extension.
If you want to copy one or more lines of code in VS Code, select the code you want to copy and then press Shift+Alt+down arrow. This will copy the line or set of lines to the bottom.
In the previous chapter, we built a form where staff can enroll undergraduate and postgraduate students. Let us add some basic styling to it before we continue building. We will also do some code refactoring. Open the project just-react in VS Code. This is the enrolment project we created in Chapter 3. Open App.js, EnrolmentForm.js, and App.css and update as per the following listings. I will explain the changes made to each file after the listings. First, open App.js and replace code as per Listing 4-1.
You can find the final project code of the chapter under the path Chapter 4 ➤ Projects ➤ just-react in the GitHub repository. You can access the repository via the book’s product page, https://github.com/Apress/Just_React.
Made a syntax change – updated the component function to an arrow function.
Added a header with the title as Student Enrolment Form:
Wrapped all input controls in a <ul> tag to improve the styling:
Added or updated classes in most of the elements. I defined the class names in the App.css file, which will follow soon.
Made a syntax change – updated the component function to an arrow function.
Removed the header from this file because we placed the header now in the App component.
To improve the styling, I wrapped the input controls within a <ul> tag. This is like what we did with App.js:
Introduced a property, value, to the first name and last name fields. This lets us reset the value to blank once we filled in and submitted the form:
The OnChange event of the first name and last name elements now calls the same function handleInputChange with the corresponding set state parameter passed to it. This function sets the input value into the state variable depending on the parameter:
onChange={(event) => handleInputChange(setFirstName, event)}
Added a new field and state variable for email. The field works just like the first name and last name, except that we specify type as email instead of text. This allows us to validate the email format.
As you can see in Change 9, I updated the welcome message slightly and included the email content.
Added or updated classes in most of the elements. You can see these classes defined in the following App.css file.

Building a basic form in React
We have Undergraduate selected by default, and the label displays Remaining UG Seats - 60. When you enter the details and click the button, the seats will reduce to 59, and the label will display the welcome message. Refer to Figure 4-1. If you select Postgraduate, the label will display Remaining PG Seats - 40. When you submit a student, it will reduce the seats accordingly.
Up to this point, we’ve added some basic styling to the form and refactored the code. We added one more email field and optimized a few functions. Now let’s build a list view to display all the enrolled students and their details.
Currently, we have a student enrolment form that allows staff to enter undergraduate and postgraduate student information. But there is no way for us to view the students already enrolled. Let’s address that in this section. We can create a view where staff can view enrolled student details. We can put the list view at the bottom of the form. As soon as staff enter student information, it gets added to the view. We will remove the current welcome message since it will not be required when we can display the added student on the list at the bottom.
I am not listing the entire component code in this section and forthcoming sections. I will provide a code section and explanation for each change, so that you can easily digest it. But, sometimes, you may want to copy or refer to the entire component code at each stage. You can find it under the path Chapter 4 ➤ Final chapter code in the GitHub repository(https://github.com/Apress/Just_React ). You can also download or clone the project just-react from the path Chapter 4 ➤ Projects. After cloning, run npm install from the project folder to install all the required node modules before running the code.
To add a Details list view, let’s create a new component first. Right-click the src folder and create a new file, and name it as EnrolList.js. Create another file EnrolList.css, just to keep the styles separate.
For the list view, let us use a Fluent UI element instead of a plain HTML element. This will familiarize you with using elements from UI libraries like Fluent UI. It comes with additional features.
Fluent UI is a collection of user experience (UX) frameworks designed by Microsoft using React. You can access the full list here: https://developer.microsoft.com/en-us/fluentui#/. There is a section for React elements and styles. You can get into this by selecting Controls/Styles under “React” from the Fluent UI home page.
This explains the code in the EnrolList.js. For now, we created a static list of four items.
A default checkbox space will appear with the DetailsList. The second class I added is to hide this space, so that it looks better. Otherwise, it will take up space on the left side of the list.

Static list in React
Now we can see a list below the form. However, it shows some static data, which we provided in the code in EnrolList.js. In the next section, let us make this list dynamic. The list must be empty to begin with. Each time when you add a student, it should get added to this list.
We are calling both EnrolmentForm and EnrolList components in the App component, which enables us to view both the form and the list together in the browser. However, we don’t have any EnrolList component tag inside the EnrolmentForm component or vice versa. Hence, there is no direct relationship between the EnrolmentForm and EnrolList components. However, there is a relationship, which is the common parent, App component. The App component connects both these components. So the EnrolmentForm and EnrolList have a sibling relation here.
As part of our requirement, we need to send data from the EnrolmentForm component to the EnrolList component and may also require the opposite. But we cannot send a prop from a sibling to another sibling. However, a sibling can send a prop to its parent, and then the parent can send it to the other sibling.
So, for the EnrolmentForm component to communicate with the EnrolList component, it must send data to the App component. Then, the App component can pass this data to the EnrolList component. Let’s see how this sibling interaction plays out.
Now the EnrolmentForm component can access the setStudentDetails function using props.setStudentDetails. Invoking this function with an object argument will set the passed object value to the state variable, studentDetails.
Let me explain the changes we made to this function compared with the last code we had. (Refer to Listing 4-2 for the previous code.)
Within the handleClick function, I added a function call to set student details. We set the property fname value to firstName. Similarly, a property key and value were added each for last name, email, and program. Apart from this, we generated a four-digit random number for id. Then, we used this id to set the key property of the student details object. The id will always be unique.
The student details object is set to the studentDetails state variable in the App component as a result of invoking props.setStudentdetails. So, now during the button click, the function handleClick sets the value to the student details along with the seats.
Earlier, we had a function call to set the welcome message inside the function handleClick. I removed this, as we are no longer displaying the message. Also, remove the variable declaration for the welcome message and the <li> tag block for the message. We don’t need to set the message anymore, since we are going to add student details to the list instead.
Here, we passed the studentDetails object and the setStudentDetails function to the EnrolList component. The setStudentDetails function is required for the EnrolList component to empty the student details once it is added to the list.
Delete the for loop and its contents, which we created earlier for displaying static items. We no longer need these static items as we are now setting up code to receive student details from the App component.
Refer to Listing 4-4 for a comparison with the previous code of EnrolList.js.
During rendering, this useEffect Hook will add the student details received from the App component to the array, items. We access the key using props.studentDetails.key. Then, the function checks if the key is empty or not. If not empty, it adds the student details to the items array. It accesses the student details using props.studentDetails. We use a spread operator to combine the items and props.studentDetails. Finally, after updating the items array, it calls props.setStudentDetails with an empty argument. This will clear the student details object.
The useEffect is not called on every re-render; it executes only if there is a change in the props. We passed props as a dependency. For now, just understand that when we pass a dependency array to useEffect, it gets triggered only if there is a change to that array. Otherwise, it will get triggered on each re-render. I will explain useEffect, the dependency array, and how exactly this works in Chapter 8.
So, when you enter the details of a student and click the button, the EnrolmentForm component sends the student details to the App component. The App component then updates the state of student details. The App component re-renders because of this state update, and it will cause the EnrolList component to receive the new state as a prop. So, when EnrolList renders, because the prop, student details, is changed, useEffect fires and adds the student item to the list. As a result, the DetailsList displays the updated list of students. The process repeats, and the list gets updated whenever a new student is added. Too easy!

Dynamic list in React
Here, I added three students, and I can see all their details in the following list. I see that the number of UG seats got updated to 58 on the remaining seats label. The one student I added is of the PG program. Clicking the Postgraduate radio button, I can see that there are 39 seats. The numbers reduced as per the corresponding program.
We have seen how two components interact by passing through their parent. In addition, now you know how to add data from a form to a list. However, what if the component tree is too large and the child components at the bottom of the tree want to interact? It may become too complicated to use this method in that case. The code will become messy. Finding out their common parent up the tree will be an exhausting task for the child components ☺. You don’t have to worry about it right now. There are ways to handle these situations. We can make use of Context API, Redux, etc. We will cover those in Chapters 5 and 8.
Next, we will look at a few more component interactions by improving our application. Let us provide edit and delete options for the enrolled student information.
In order to add editing and deleting options to each row on the list, we need two icons. Let us use the react-icons library for the icons. Open the terminal, and press Ctrl+C followed by Y to stop the server. Install required modules by running npm i react-icons.
React Icons is a consolidated library that has a lot of icons to choose from. You can use any available icons. You can see a full list here: https://react-icons.github.io/react-icons. You can search for the icon name and can see a list of icons. All these libraries get installed as a part of installing the react-icon package. I am using the material design icons in this example.
With this change, we are sending a delete icon and an edit icon, along with each student row, to the EnrolList component.

Actions on a list
Let us now implement the functionalities for editing and deleting student information. Let us start with the delete option first. To delete a student row, we need to attach an onClick event to the delete icon. We need to define this onClick event in the EnrolmentForm component. This is because we are passing edit and delete as the properties of the student details object from the EnrolmentForm component.
In the event listener function, there needs to be logic to remove the specific row from the items array. Importantly, this should update the details list. Of course, we can use the student id as a key to identify the row.
So this expects a new prop, handleItemSelection, to be passed from the App component. Before modifying App.js, let us update App.css by adding the following class to give some styles for these edit and delete icons.
Here you can see that the function updates both the action and the id state variables using the received parameters.
This function is to restore the number of available seats when a deletion occurs. When restoreSeats is called, it restores the seats to its original state. If we delete a UG seat, it will restore the UG seats by adding 1; and if we delete a PG seat, it will restore the PG seats. We can pass this function as a prop to the EnrolList component, so that it can restore the number of available seats once the user deletes a row from the list.
From the EnrolmentForm component, the handleItemSelection function is invoked when we click the delete icon using props.handleItemSelection.
So, if the user clicks Delete, it invokes handleItemSelection inside the App component. When the function executes, we will have the word delete stored into the variable action and the selected item id in the selItemId variable.
Now we added three more properties to the EnrolList tag. We are passing the action and the id. Besides that, we are passing the function restoreSeats as a prop. The EnrolList can call it after the deletion, so that it will restore the number of available seats.
Run npm start if you haven’t already. Try adding multiple items and deleting items. It should remove the corresponding student details from the list and update the seats accordingly.
To sum up, in order to achieve the delete functionality, we built a multicomponent interaction in the application. The EnrolmentForm component builds the student details rows, along with edit and delete buttons. We pass these to the EnrolList component when the user clicks the Enrol button. If a student row is to be deleted, the EnrolmentForm component starts the action and passes the details to the EnrolList component via the App component. The EnrolList component then deletes the item and updates the student list. It restores the state of the seats using a communication between the EnrolList and App components. React does all these things quite fast by changing state within components and by making communication possible between the components. You can feel how quickly these actions happen in a browser screen. I know you are excited! Let us move on to implement the edit functionality next and keep on learning React.
As we have all the required information within the EnrolmentForm component and are updating the information using the form, implementing edit details does not require a back-and-forth component interaction like deleting.
As soon as the user clicks the edit icon, we need to bring the details into the text fields, so they can edit them and click the button to update. This should update the details on the students’ list. We need to change the button’s text from Enrol to Update if the action is edit. Last, we need a cancel button so the user can cancel the changes if they want.
Go to EnrolmentForm.js and make the following changes.
We will set this function to be invoked when the user clicks the edit icon. First, it calls handleInputReset, which sets the field values of the selected row to the first name, last name, and email text fields. In the next line, the function sets the selected student id to the state variable. Because of this, we ensure that the right row gets updated when the user clicks the Update button. Also, this function changes the button text from Enrol to Update. This differentiates it from submitting a new student.
In the first line, we are updating the state variable studentID using setStudentID(randomKey). We are setting the random number value to the studentID variable here. This is the same number that we are storing in the variable id and passing as the key during click on the edit.
The second line specifies a condition. It says to use the random generated number as the student id if the button is Enrol and use the state variable studentID value if it is Update. This is because, if the button is Update, we cannot use the random number since it would create a new item instead of updating. So we specified to use the state variable studentID there. This variable will have the selected student ID.
We update the state for studentID, but it will not get reflected to the variable immediately. Therefore, we are using the random number itself as the key if the button text is Enrol. That means during a new student enrolment.
Here, we added an onClick event and pointed it to the handleEdit function and passed the selected student ID as a parameter. If you look at the handleEdit function we defined earlier, you see that it sets the studentID variable to the selected student id. Also, it sets the button text to Update. So this ensures that when the edit icon is clicked, the button text is changed to Update.
Compared with the previous code, there are two buttons now. The Enrol button now has an assigned class, btn. The button text is now dynamic, and we initialized it with the value Enrol. The Cancel button has the same class but a different id.
Now we have a defined class to define styles for both the Enrol button and the Cancel button. If you view this form in a browser, the form will still look like before. However, there will also be a Cancel button.
When you click Edit on any row in the list, the selected student details will now appear on the screen along with the Update and Cancel buttons. You can change any field value, first name, last name, or email. When you click the Update button, the corresponding list row gets updated. Clicking Cancel will clear the field values and display the Enrol button again. Let’s look at the app in the browser. Refer to Figure 4-5.
Run npm start if it’s not already running. You can keep it running and view the changes in the browser as and when you type.

Editing a list
For example, when I clicked the edit icon against the second row, the details got displayed in the form to edit. At the same time, the button text got changed to Update. If I make any changes and click Update, the corresponding row gets updated. Otherwise, if I click Cancel, the form gets cleared. After Update or Cancel, the button text will get reset to Enrol. Try to create multiple items and try to edit and delete them.
However, we did not yet complete the edit implementation. Only, the student details we can edit at this stage. We are yet to work on implementing a solution for updating the program and seats details. The program and seat details will not get updated as expected now. Let us implement that next.
The students belong to two kinds of program in this app, Undergraduate and Postgraduate. Imagine adding a postgraduate student and later editing it. At this time, the radio button selection may not be on postgraduate. We are only sending data to the enrolment form to display the selected student details. However, we are not sending data to the App component to choose the corresponding program of the student. Also, we need to update seats when a student switches a program from undergraduate to postgraduate or vice versa. Let us implement that.
Selecting a student and editing it should auto-select the corresponding program radio button. Also, the user should be able to change the program and save it back on the list. Importantly, all this should display the remaining seats accordingly. For example, let’s say you added a UG student, and the seats got changed to 59. The next time, when you are editing and moving the same student to the PG program, the UG seats should get updated back to 60, and the PG seats should get reduced by 1.
We set the checked property for both radio buttons. For UG, we set it to the value of the isUGChecked variable; and for PG, we set it to the opposite value of the isUGChecked variable. We initialized the isUGChecked variable with the value true. Because of this, we will have Undergraduate selected by default.
The function receives a parameter selProgram. If selProgram is UG, it will set the state variable isUGChecked to true, which means the Undergraduate radio button gets selected. If the selProgram is PG, it will set isUGChecked to false, which means the Postgraduate radio button gets selected. Next, we set the program variable to the selected program to display the correct label. This ensures the label will display the remaining UG seats or PG seats as per the program. Last, we set the isRestoreSeats variable to true. This implies that we need to set the number of available seats accordingly. We will handle this later in the handleChange function, that is, when a program is switched.
The props.setSelectedProgram(program) line will invoke the setSelectedProgram of the App component by passing the value of the program into it. This will pass the program of the selected item to the App component. Subsequently, the function setSelectedProgram in the App component will select the radio button accordingly.
When we select a student to edit and if we change their program from UG to PG or vice versa, this part of the handleChange function is called. This increases the number of seats in the previous program by 1.
Let me explain the concept with an example. Let’s say you added two new UG students, John and Ithal. The number of UG seats now gets reduced to 58. When you click edit on any of those students, say John, handleEdit will be called. Inside handleEdit, we are calling props.setSelectedProgram. This invokes the setSelectedProgram function in the App component. We have a line in this function to set isRestoreSeats to true. Suppose you changed John’s program from UG to PG. Now, the handleChange function is called. It checks if isRestoreSeats is true, and it finds it is. Then, it checks John’s current program, which is PG. Therefore, it increases the previous program, UG, seats by 1. This way, it restores the previous program seats when you switch programs.
As soon as a seat gets increased, the function sets IsRestoreSeats to false. This ensures that if a user clicks a radio button multiple times, it won’t increase the seats again. Afterward, if the user clicks edit on any student, the function will set IsRestoreSeats back to true.
Go to the app and try to create a program change scenario, as shown. For example, I added two UG students and one PG student. The seats will read 58 and 39, respectively. Click edit against a UG student and switch the program to Postgraduate using the radio button. If you click back the Undergraduate radio button, the UG seats will be 59 now. Even if you switch back and forth several times, the seats will remain at the same number. If you keep it in Postgraduate and save the form, the PG seats will become 38. You will see one UG student and two PG students on the list now. At the same time, it will display the corresponding remaining seats.
We completed a working React frontend application at this stage. You can experiment with different scenarios.
As mentioned in Chapter 3, this book contains listings and code sections that have been tested and verified in VS Code, so there is almost no chance of an error occurring. However, due to unseen formatting issues, if some code won’t work or functionality is unexpected, ensure that you take the corresponding component file code or clone the entire project, from GitHub. As mentioned before, you can access the repository via the book’s product page, https://github.com/Apress/Just-React. There you can find the final project code and each listing of the chapter under the folder Chapter 4.
In conclusion, we focused primarily on coding in this chapter. My goal was to familiarize you with the component interactions and make you think the React way.
We began by building on top of the student enrolment form, which we started in the last chapter. We talked about Fluent UI controls. Afterward, we discussed how a component can interact with another through their common parent component. We built a complete frontend form for student enrolment. You learned about adding items to a list, working on selected list items, etc. You learned how to achieve all these without having to touch the DOM. We implemented all these features purely using state management. You learned the better usage of concepts like props, state, Hooks, etc.
This chapter was primarily based on the enrolment form application. We constructed the application by relying on the basic React concept of components and state management. Each component represents a single task, and the components communicate to keep the app together. The enrollment form has the functionality of adding/updating details, and the enrollment list component displays them as a list. The App component holds these two components together and also handles updates to seats and programs.
In the next chapter, we will discuss a few more advanced concepts in React. You will learn about React Lazy, Suspense, props drilling, Context API, etc. In addition to improving this enrolment app, we will create a new React project to illustrate the concepts. Think React and prepare to rethink in the next chapter!
In the previous chapter, we built a complete frontend project for a student enrolment form. This chapter is about “re-”: rethink, redesign, rebuild, and restructure React apps in React way. We will discuss mostly about rebuilding things in a better way. You will learn more advanced concepts of React in this chapter. We will check how these features can improve our existing solution.
The first thing we will do is learn about code splitting. You will learn about the Lazy function and the Suspense component. We will apply code splitting into our enrolment application. Next, we will discuss potential issues in our application. You will learn about props drilling and how to solve a potential issue with that by redesigning components.
In the next section, we will create a new single-page application (SPA). The application will support multiple user views. The application will teach us more about component interaction. We will talk about React fragments.
Then, we will explore a relatively new feature of React, which was introduced with React 16.3. The React Context provides an easy way to manage the state between components without drilling through them. We will learn to use the useContext hook.
At the end of this chapter, you will be proficient in designing and creating React apps following the most recommended and most current approaches.
To find out which version of react and react-dom you are using, type npm view react version and npm view react-dom version from the Visual Studio Code (VS Code) terminal of the project. We are using React 18 for all projects in this book.
Think about our enrolment form project. We have the form and list components. When you first load the page, do you need the list to load? Not really. Even though the list is empty, we do not require it to load.
Both the components are child components of their parent component, App. The browser can load only the form component and can load the list component later. We can achieve this goal by splitting our App component here to allow it to load at different times in the browser. We refer to this as code splitting. This is an important functionality of React, especially for large single-page applications (SPAs).
This will not make a significant performance improvement in our simple project. However, this can be quite useful for larger applications. Imagine our application is large. Webpack bundles all the files and includes them on the web page when it loads. For larger applications, this bundle can get very large and slow down the application. We can break this bundle into smaller chunks. When loading a page, it will load only the required chunk first. Other parts will load later. That’s the concept of lazy loading. With the Lazy function and the Suspense component, we can achieve this code splitting.
Let me illustrate this with our enrolment form project. Open the just-react project (enrolment application project) in VS Code from where you left in the last chapter.
Refer to the GitHub repository Chapter 4 section for the latest code of the just-react project. You can access the repository via the book’s product page, https://github.com/Apress/Just_React. All code listings and final component codes of all projects are available there.

Show Coverage

Coverage before code splitting
I wrapped the EnrolList inside a Suspense component. This is required by the Lazy function to wrap the lazy component. I also added a fallback property. With this, I ensure that if the lazy-loaded component cannot load, it will display the fallback div. In our case, the fallback div contains only a message.

Simulating a slow network
After setting the network, click the reload button inside the coverage.
You will see the message “Enrolled student details loading…” for a second before the coverage loads. This shows it loaded the EnrolList component after the initial load.

Coverage after code splitting
Compared with the previous version (Figure 5-2), the browser loaded two more files, src_EnrolList_js.chunk.js and vendors-noder_modules_fluentui-react_lib_components_DetailsList_DetailsList_js.chunk.js.
So, here, initially the web page loaded the bundle without the EnrolList component. Then the EnrolList component and the DetailsList inside that component loaded in two additional chunks. This shows how code splitting helps load components in chunks.
The app will still work as before. You can enter student details, and the list will get updated. Code splitting can be very useful when we build complex single-page applications in React.
Remember to reset the network back to “No throttling” from “Fast 3G.” Otherwise, you may experience slow network performance while you continue to work on the enrolment project from the next section.
By props drilling, we mean sending props from a higher-level component to a lower-level component. In Chapter 4, in the enrolment project, we passed props down the component tree. For example, the user can select a program, undergraduate or postgraduate, and we pass this value down to the EnrolmentForm component. This is because we need to know what program we selected when saving the student details on to the list. Here’s the catch: do we really need the value of the program in the EnrolmentForm component? No. In the EnrolmentForm component, we are entering student information. We designed the component for this data entry. It does not need to know about the selected program. We are capturing it in the EnrolmentForm component only to pass it on to the EnrolList component where this program value is required. That is passing props through a component that doesn’t need them at all. This is a major disadvantage of props drilling. The same is true for seats. We can handle seat management between the App and EnrolList components without passing it through the EnrolmentForm component.
If your application is complex, imagine what it would be like. Managing the application through props drilling will be extremely difficult due to the large component tree. By using a concept called React Context, we can avoid this issue with props drilling. Context is an API built into React, and it provides an alternate and more easy way to pass data between components without having to use the props. We will learn more about Context in the later sections of the chapter.
In this section, we will look at how to fix flaws in component interactions. We can fix the preceding issue without using Context. We can improve the way of passing the prop program, for example. To avoid this props drilling problem, I recommend analyzing the component tree and looking for ways to improve it. With respect to the enrolment app, let’s look at how we can do this.
Continuing from where you left off in the previous section, open the just-react project. Our plan is to modify this project to avoid the existing props drilling issue. By making the App component pass the program directly to the EnrolList component, we won’t have to go through EnrolmentForm.
To ensure that you can easily capture the changes, we will modify the component code of these three components in three steps.
Step 1: We modify App.js. The goal is to avoid passing program and seat information to the EnrolmentForm component, but instead, pass them to the EnrolList component.
We previously passed six parameters to the EnrolmentForm tag. Now, we are passing only the two functions setStudentDetails and handleItemSelection as the props. Let’s recap what these two functions do. The setStudentDetails sets the entered student details to the state variable studentDetails. The handleItemSelection sets the selected student id and the selected action to the respective state variables.
Earlier, we were passing four more props to EnrolmentForm: chosenProgram, setSelectedProgram, currentSeats, and setSeats. The chosenProgram and currentSeats are the values of the selected program and the seats available for that program. The functions setSelectedProgram and setSeats are the function props the child component can use to set the selected program and the number of seats available. Our goal is to pass the program, seats, and these functions to EnrolList instead of EnrolmentForm. For this reason, we removed all these four properties. We now need to add these four props to the EnrolList tag.
So now we have a total of nine props passed to the EnrolList component. We are passing seats, program, and the two function props directly to the EnrolList component.
Let us look at the changes done in the function. From the existing code, we removed the program parameter and the call to the setSelectedProgram.
At this point, you can find the latest code for each component of the just-react project in the Chapter 4 section of the GitHub repository. You can access the repository via the product page of the book at https://github.com/Apress/Just_React.
Additionally, I added props.handleItemSelection("edit", stId). It’s the same thing we did earlier for delete. Now the handleItemSelection function in the App component will be triggered every time the user selects a student for editing. This will update the values of the state variables action and id in the App component. We already passed these variables as props to the EnrolList component. So the EnrolList component will receive the updated state.
Previously, in this function, we were setting available seats using props.setUpdatedSeats(props.currentSeats - 1). We removed this as our objective is not to have references to seats in this component. We will set this up in the EnrolList component.
In the previous version of this function, available seats were set by props.setUpdatedSeats(props.currentSeats - 1). As we want to do this from within the EnrolList component, I deleted this line.
That’s all the changes to the EnrolmentForm component now. Now, we removed all program and seats references inside the component. Also, we updated the handleEdit function to pass the action and student id during an edit.
The first line sets the selected program to the studentDetails object. The EnrolmentForm component no longer passes the program. So we set the student’s program in this component based on the program selected. In the second line, the function prop setUpdatedSeats is invoked to reduce the seats by one according to the selected program. The number of seats is reduced by one when we add a new student. This was previously done in the EnrolmentForm component during the button click.
With the preceding changes, the delete function will now work. For the edit to work, we need to add a useEffect method to the EnrolList component.
The existing useEffect will get triggered whenever there is a change in the props, since we passed the entire props object as the dependency. However, we want the edit to be triggered only when the handleEdit is called from the EnrolmentForm component. The handleEdit updates the state of the action and student id in the App component. So we need to create another block with props.studentId or props.action as the dependency. Let us use student id.
Here, we are getting the selected item similar to what we did for the delete. After that we are invoking the function prop setSelectedProgram with the current item program as the argument. This will update the radio button selection to the corresponding program and will restore the seats. This function we have already defined in App.js.
If you would like to view the complete component code at any time, refer to the GitHub repository (https://github.com/Apress/Just_React). You can find each component code under the path Chapter 5 ➤ Final chapter code ➤ just-react.
That’s all the changes we needed make in all three component codes. In conclusion, we pass the id and action from the EnrolmentForm component to the EnrolList component through the App component. The EnrolList component then communicates with the App component to update the program and seats. The EnrolmentForm component is no longer connected to the program and seats.

Right way to pass the props
We redesigned the app to work better. We avoided the props drilling issue with the program and seats props and still achieved all the functionalities. You can keep the enrolment project aside for now. Next, let us create a single-page application with multiple user views.
In this section, we’ll create a single-page app with multiple views. The end user will experience it as a multi-page website, but we will implement it on a single page without having any navigation to any other pages. We take care of loading and unloading components through state management. As I mentioned before, Netflix, Airbnb, PayPal, etc. are examples of single-page applications (SPAs).
Imagine you are running a small food shop. You have preprepared chicken burgers, veg burgers, chips, and ice creams available for sale. The customers can only order food online with the option for pickup. Customers can only pay cash during pickup. You want to develop a React application to handle sales.
In the root component, say App, we store a list of food items and their respective remaining quantities. In another component, say Foods, we display the list of food items. Customers can view this page and click each item. Whenever a user clicks any food item, the user will get into an item page that displays only the selected item. Customers can select the quantity and click Submit Order. We will have another component called FoodOrder for this item page. Upon ordering, it should decrease the respective food item’s quantity, depending on how many of the item the customer ordered.
The menuItems object array variable contains the initial quantity of each of the four food items in our menu. The setMenuItems function can update the menu items or existing item’s properties. For example, we can use this to set the item quantity after the user placed orders. In the JSX code, we have a menu element (<ul>) besides the title sections. I added a map function to loop over the array menuItems and create <li> tags for each menu item with its name and quantity.

App component with static object values
If you want to add another menu item, you can just add it to the menuItems array in the code, and the app will have it immediately reflected.
So we created a component that allows you, the food shop owner, and staff to view the current menu availability. Customers cannot see this. Let us create another component, say Foods. The component will display all the four items along with a small description, price, and image. This will be the customer’s home page. We will have a button to switch between the foods display and the availability display.
Let us prepare the images before we create the Foods component. Right-click the src folder and select New Folder. Name the folder images. Within the images folder, add four images named cb.jpg, vb.jpg, chips.jpg and ic.jpg. Make sure the names match those of the image property of the menuItems object in the App component.
You can access the images that I used from the GitHub repo (https://github.com/Apress/Just_React). The images are located under Chapter 5 ➤ Food images. All the four images are from unsplash.com, and those images are free to use.
The Foods component expects a prop from the parent component, from which it is called. Here, we need to pass menuItems from the App component to the Foods component. The prop is foodItems. By looping through the foodItems, it creates a view of the food image, description, and price. Like in App.js, we use object properties here for the image and other content.
We wrapped all the elements in the return statements in a React fragment (<Fragment></Fragment>). It is not possible to keep multiple child elements without a container element inside a JSX expression. Hence, we wrapped all child elements inside the return function using a fragment. Also, instead of using the syntax <Fragment></Fragment>, you can also use <></>.
Fragments in React allow us to group items without having to wrap them inside another element, such as a div. Here, in our case, there is no need to add a new div. Instead, we can use a fragment. It is important to note that fragments do not add extra DOM nodes, whereas a plain <div> naturally does. If we want to add styles to the container or if it serves some other purpose, we can use a div element as a container. It is unnecessary to add an extra node otherwise. We can instead use a fragment. You can see there isn’t an extra node for the fragment if you run the application in the browser. Press F12 and see the HTML under the dev tools.
To view the Foods component in the browser, we need to add it to App.js. To do this, let’s first create a button that will switch the view between food availability and food selection. In a real-world scenario, the availability of food is only visible to admin users, such as the shop owner or staff. We will deal with this in Chapter 9 when we learn about authentication.
By default, isChooseFoodPage is false. Because of that, the button text will show Order Food by default. When you click the button, the text will switch. I already defined the styles of the button in App.css in Listing 5-2.
Next, we added a condition around the Menu Availability header text and menu items. Here we have a condition that says if isChooseFoodPage is false, then display the component. We wrapped the header text and the <ul> tag for menu items inside a fragment. Here we have a JSX expression, !isChooseFoodPage. We define the menu items list and the header text elements inside that expression. We cannot keep the multiple child elements without a container inside a JSX expression. So we added an argument. As the title Just Food Online Shop is the same in both scenarios, we kept it outside of the !isChooseFoodPage expression.
The last change is that we added the Foods component and passed menuItems as a prop to it. We added a condition to display the Foods component, which is the opposite condition of the preceding scenario, where we displayed menu items and the availability header .
If isChooseFoodPage is true, the Foods component gets displayed by default. If the user clicks the Order Food button, it changes the text to Availability Check, and it will display the Foods component.

Foods component
Whenever you move your mouse over any of the food items, a cursor appears. We added a cursor style to the food items. You can click Availability Check and switch back to the Menu Availability view.
Our next task is to create a component that can display individual food items so that the customer can order food. Keeping it simple, we’re going to allow customers to order only one item at a time. Customers will need to select one or more quantity, provide their name and mobile number, and then click Submit Order. Once ordered, a message will appear on the customer’s screen. In the back end, we should reduce the availability accordingly. If they want another item, they need to go back to the Order Food page (Choose from our Menu) from our menu availability page to select the item again, select quantity, provide details, and place a separate order.

Let us look at the JSX we defined first. We have the image, the description, and the price of the selected food displayed in this component. It is expecting a prop, selectedFood, from its parent component. So here we expect the Foods component to pass the selected food item object. The FoodOrder component retrieves properties from the object, like the name, image, etc.
We initialized the quantity to 1 and the price to that of the selected food. For example, if you select Ice Cream, both the quantity and price will be 1 and $4, respectively.
As soon as the customer selects a quantity, the state variable totalAmount gets updated with the selected quantity multiplied by the amount. Besides that, it sets the selected quantity to the variable quantity.
Look at the JSX again. Below the quantity input element, we have text inputs for name and mobile number. There are no operations set for these fields; it is just for entering the data. Finally, we have two buttons at the bottom. First, let’s inspect the right-hand-side button, which is the Return to Menu button.
Upon clicking this button, we need to hide the FoodOrder component and display the Foods component to order food items. This button calls a callback function props.returnToMenu. We will need to define this function in the Foods component and pass it as a prop.
In the first line, the function sets the IsOrdered variable to true. We defined this variable and initialized it with false. If IsOrdered is true, we will display a label underneath the buttons that says you submitted the order. We defined a label with a condition below the buttons for this purpose.
In the second line, the handleClick invokes props.updateQuantity with two parameters, the id of the selected food item and the selected quantity. By calling this function, it invokes a function in the parent component, Foods, to set the quantity.
So this means, in the Foods component, we need to pass three props to the FoodOrder component: the selected item and two function props for returning to the menu and updating the quantity.
Next, let’s update the Foods component again to include the FoodOrder component and pass the required props.
In the return statement, we enclosed the food details and title in a fragment. This section will only display if selectedFood is empty. This means that when the customer selects a food, we hide the Choose from our Menu section from the user.
We have the food details such as name, price, and image stored in the selectedFood property. The callback function returnToMenu calls setSelectedFood with an empty parameter. Therefore, when the child component invokes the returnToMenu function, the selectedFood variable becomes empty. Because of this, the app displays the Choose from our Menu section and not the FoodOrder component.
The third property, updateQuantity, is a callback function. This function invokes updateQuantity of the App component using props.updateQuantity. This means we will have to pass a new function prop from the App component. We will do it shortly.
We are passing the selected item id and ordered quantity from the Foods component. The Foods component receives the same from the FoodOrder component as parameters to this function prop.
We defined data-id of each <li> tag as item id. This function loops through the food items and compares the id with the data-id of the <li> tag. Finally, it sets the matched food item to the selectedFood variable. As soon as this happens, the FoodOrder component gets loaded, and Choose from our Menu disappears. This is because we set a condition around these sections to make the FoodOrder component visible if selectedFood has value.
This function receives the id and orderQuantity parameters. It copies the array of menu items to the updatedMenuItems variable. Then, it finds the ordered menu item using the id and updates the quantity by subtracting the orderQuantity. It then sets the updatedMenuItems to the menuItems variable using the setMenuItems method. This updates the menu items by reducing the quantity of the ordered food item.
We already updated the Foods component to call props.updateQuantity when its child, FoodOrder, invokes its function prop updateQuantity.
Run npm start to view the app in the browser. Click Order Food and select one of the food items. When you select it, individual food details appear with the option to submit order. If you increase the quantity, the price will increase accordingly. When you submit, you will get a confirmation message. If you click Return to Menu, all the food items will be available to select again.

FoodOrder component(Steps: 1, enter quantity; 2, enter details; 3, submit order; 4, receive message; 5, check availability)


App component updated from the FoodOrder component
The quantity updated based on the ordered quantity of the respective item. You can experiment with other food items and order different quantities. The availability should update based on that.
The app works as expected. But as you may have already noticed, we have a props drilling issue in this quantity update. We are sending the ordered food item id and quantity through the Foods component, which does not require these values at all.
As compared to the enrolment project, there is no redesign we can do here to avoid the drilling issue. The only way to transfer these data from the App component to the FoodOrder component is through the Foods component. So how can we avoid the issue with props drilling? Let’s see.
As part of the student enrolment project, we fixed the props drilling issue by designing the components in a better way. We had an App component and its two child components. This allowed us to redesign, passing the props directly to the right component. However, for the just-food project, the third component, FoodOrder, is nested within the second component, Foods. So, here, we cannot pass the properties from the root component, App, to the third component without passing the properties through the second component, Foods.
Because the second component does not require the props, we have a props drilling issue. We can solve this by using Context. As we mentioned before, Context is an API built into React that provides an alternate and more convenient method of passing data between components.
Using Context, we can create a kind of global state that can be used by all components. To implement Context, we need three steps. Create a context, provide it from a component, and then consume it from any other component that requires it.
To help you better understand this, let us fix the props drilling in our just-food project with the help of Context.
We have now removed all the code for updating quantity. If you run the app now, you observe that it will not update the quantity on the Menu Availability page after you ordered an item. Let’s reintroduce this feature in a better way using Context.
This step creates a context using the method createContext. We created the context and stored it in the variable foodItemsContext. We are exporting this in a variable, so that we can use it in our FoodOrder component.
This means that our parent div element, including its children, is now included inside of the preceding tag. In this context provider, we put the value as menuItems. Therefore, the menuItems object is now provided in this context.
Now, the function checks menuItems and updates the quantity if the id matches that of the ordered item.
You can view the app in the browser now. Try ordering items, and you can observe that quantity gets updated exactly as before, this time without drilling props through the Foods component! We haven’t done any coding in the Foods component for this purpose. The Foods component does not have to worry about the quantity here, as we pass the context from the App component directly to the FoodOrder component. When you update the menuItems from the FoodOrder component, the Availability Check page gets updated with the quantity of the ordered item. Context changes, like state changes, cause a re-render of the components. The context solution has fixed the props drilling problem, and the app now looks much cleaner.

App design without Context

App design with Context
You can visit the GitHub repository (https://github.com/Apress/Just_React) to view the project code at the end of each chapter. The just-food project with Context implementation is located under Chapter 5 ➤ Projects. You can download or clone the entire project at the end of each chapter from the GitHub repository. After cloning, run npm install from the project folder to install all the required node modules before running the code.
Our focus in this chapter was rethinking in React way. We did a lot of practicing in this chapter. We began in a lazy mode by learning about code splitting using Lazy and Suspense. React’s code splitting feature can be extremely useful when coding complex applications.
Our next discussion focused on a common issue with React, which is with props drilling. After that, we went back and reanalyzed our student enrolment code. Props drilling and a few other issues we found there led us to redesign the components. Finally, we built it by eliminating the props drilling issue.
In the subsequent section, we built a different application called just-food. There are multiple views in the application. We built everything on a single page. You learned more about component interactions and conditional display. You learned about React fragments.
After another rethink, we found the props drilling problem that we could not fix with any kind of redesign because of the nested component structure. This is where another React feature, React Context, came into play. We redesigned the app using Context. This allowed us to bypass the middle component and share the state between the first and third components. You met with the Hook “useContext”.
I guess we can relax a bit in the next two chapters. We will focus on debugging and styling React applications there. I will introduce you to a few helpful tools and libraries in the next two chapters. More advanced features of React await you in Chapters 8 and 9. See you then debugging React in the next chapter!
This chapter discusses different ways to debug React applications. It is mostly about how you, as a developer, react to bugs and issues in React applications.
In this chapter, we will start with the Chrome developer tools, which most of you should already be familiar with. If you are already proficient in the Chrome developer tools, you may skip that section. From there, we will move to our just-food application, which we developed in our last chapter. We’ll break the just-food app by creating some errors and then look at how the Chrome tools can help us fix them.
We will discuss error boundaries and realize that they are not applicable to our functional components. But don’t fret. We will create a friendly error page for our users.
We will then explore and learn how to use the React DevTools. You will learn about using the Components tab and how to change props and state on the go. We will then discuss finding performance glitches with the help of Profiler. We will conclude this chapter by discussing debugging within Visual Studio Code (VS Code). You will learn how to set breakpoints, do debugging, and log in VS Code.
By the end of this chapter, you will be more excited about debugging React applications than developing them. This chapter will be a smooth and relaxing ride compared with our code-rich chapters.
During our initial chapters, we covered the Chrome dev tools, a set of web developer tools that comes with the Chrome browser. This tool has a lot of powerful features for debugging web applications. It’s your go-to tool for finding issues such as bugs, style issues, performance issues, etc.

Open the Chrome DevTools

Elements tab

Inspecting an element
From the right window, you can change the styles. For example, you can change padding-bottom of the liApp class to 25px. You can add a new style, say color:Red. This will get immediately reflected in the app. This way, you can inspect each HTML element and view the updated style in the browser. The style will be active for the browser session only, and it will be lost once you refresh the browser. This will help you determine the desired look for the app. Once you are happy with it, you go back and copy the updated style into the respective CSS file of the app in VS Code. I updated padding-bottom and the color of the liApp class in the following. Since this class is common to all food items, it gets applied to all items.

Updating styles
You can check and uncheck individual styles using the checkbox option (in blue).
This way, you can inspect elements and determine the desired styles for each element and then update or create classes in the app. Let’s look at the third tab, Sources, next.
This section shows how to debug React code by using the DevTools. To do so, we will use the Foods component, which we built for customers to order food. Click the Order Food button at the top and select any of the food items from the resulting page. When you select the item, it opens the food order page with the details of the selected item.

Sources
I highlighted all the preceding steps in Figure 6-5.
When you change the quantity, the debugger will pause on line 14, where you set the breakpoint earlier. When you hover over selectedFood.price, you would notice the value 24 there, if you had selected Chicken Burger. Similarly, you can check the value of event.target.value. On the top, you can see the message paused in debugger. Next to that you can see two buttons.
The first one is to resume script execution. Clicking it will continue the execution, and it will move to the next breakpoint if you have one. Otherwise, it will get completed. You can use the F8 key as an alternative to do this. For example, when you click the script execution button, when you are at line 14 in the preceding example, it will move to line 19, where you set the next breakpoint.

Debugging the source

Viewing point-in-time values at Console
We can continue execution by pressing the F8 key. When you click the Submit Order button, it will hit the breakpoint at line 19. You can navigate through menu items to check how the map function works over there. You can remove a breakpoint by clicking the line again. By using breakpoints and the console effectively, you can uncover bugs and performance glitches and update your code accordingly.
You can view any errors and warnings in the Console tab. It also provides the detailed error messages in red with the line number and other details. In addition, you can log any results into the console by adding the logging into the code. Let’s look at how these things work with an example.

Logging into the console
You can remove these console logs from the code now. Next, let’s create an error and check how the console displays it.

Console errors
Besides the details, the error provides an idea of how to track it down. Also, you can spot the filename and code line on the right. If you examine the error, you can see that the handleQuantityChange function was called before you updated the quantity. And it didn’t find any value for the event, so it threw the error “Cannot read properties of undefined (reading ‘target’).”
onChange={handleQuantityChange} – Here the event is passed by default.
onChange={(event)=> handleQuantityChange(event)} – If we use an arrow function like this, we need to pass an event specifically.
So these are the two ways to include a reference to the function call. When we do onChange={handleQuantityChange()}, that calls the function itself instead of referring. That throws the error immediately.
The preceding was an example of how we could detect errors from the console and use it to resolve issues. Now, before you revert the code and fix the error, let us display a fallback interface to the user in case of an error.
As you can observe from Figure 6-9, the browser gives us a suggestion in the second error, where it suggests that we consider adding an error boundary. That’s actually a wonderful suggestion, but let’s see if we can do it in the next section.
Error boundaries are components that help us catch errors and display a different UI to the user. By doing so, we can avoid breaking the app and display a user-friendly interface to the user. However, we cannot use error boundaries in functional components. We built the just-food app with functional components. This book’s focus is on building apps using functional components and Hooks.
Let’s use the JavaScript method of try-catch blocks and insert some state behavior into it. We can also use it to handle error handling.
Whenever an error occurs, it will set the state variable isErrorCatched to true.
The just-food project with the ErrorFunctionalBoundary component implementation is located under Chapter 6 ➤ Projects in the GitHub repo (https://github.com/Apress/Just_React).

Handling errors
You will no longer view this specific error in the console since we handled it in the application. You can always comment on the try-catch sections during development if you want to view console errors. Once the build is complete, you can enable it again.
As a best practice, include the ErrorFunctionalBoundary component in all other components. Then, use try-catch blocks to capture errors and set state. Hopefully in the future, there will be some better ways to handle errors with new React versions.
The React developer tools are an extension to the Chrome DevTools. This provides a better view of component trees for debugging, as well as the ability to inspect and edit props and states. Using our just-food app, we’ll make out how it works.

Adding the React Dev Tools extension
Now that you have opened the app and pressed F12, you can see two more tabs: Components and Profiler. Restart your browser in case you don’t see them.

React DevTools – Components
You can view all the props of the selected component. Expand it to view the details. If you edit the values, the changes will get updated in the browser.
The Hooks section shows the context and all the state variables of the selected component. You can change the state and look at what happens. If you click the checkbox against the third state (in Figure 6-12), the message Order Submitted appears, which is because it sets the isOrdered variable to true. Upon ticking the checkbox against the fourth state variable, the application displays the ErrorFunctionalBoundary component as isErrorCatched is now true. You will notice the message We'll be back shortly. This way, you can test the component behavior in the browser. This makes the development quite easy.
It is also possible to select other components from the component tree in the left pane. You can read and update props and states from the browser.

React DevTools – Start profiling

React DevTools – Stop profiling

React DevTools – profiling data
React has two aspects: renders and commits. A render determines what changes need to be made to the DOM. React calls the render and compares the results with the previous render. After comparing, React decides what changes should apply to the DOM and then applies those changes. This is called a commit.
Figure 6-15 shows six commits. These are displayed as a bar chart on the right side. By default, it will have the first commit selected. We can click each bar to view all the commits one by one.

React DevTools – commits

React DevTools – Ranked

React DevTools – commit filter
Despite what we have discussed, React Profiler capabilities do not end here. There is a lot to explore when you become more and more experienced in React. But for now, we have covered a good amount of information on Profiler regarding advanced React development.
That was all about the powerful and the impressive React developer tools. In the next section, let’s jump on to VS Code for some in-house debugging there to make a developer’s life easier and more exciting!
I showed how to debug React apps using the Chrome developer tools in the first section. Would it be easier sometimes to debug using VS Code? Yes, there are built-in debugging features in VS Code, and we will use them to debug our just-food app.

Create launch.json

Select an environment for the debugger

Debugging in VS Code
In the top bar, you’ll find buttons for stepping through the code, restarting, stopping, etc. At the bottom, we have a Debug Console. You can do console logs at the arrow point, and it will appear in the console.
The Watch option is on the left side of the screen. With Watch, you can observe the real-time value of variables and expressions. We can see the value of the object selectedFood when you select an item and see how it changes when the browser loads the selected item.

Using Watch

Watch evaluation
This way, you can watch the point-in-time variable value without having to enter it in the console and check every time.
You can visit the GitHub repository to view final chapter project code (https://github.com/Apress/Just_React). Also, all the listings of this chapter are located under the path Chapter 6 ➤ Listings. You can also download or clone the entire project at the end of each chapter from the GitHub repository. After cloning, run npm install from the project folder to install all the required node modules before running the code.
During this chapter, we discussed error catching and different ways to debug your application. We began with learning about the Chrome developer tools. We discussed different tabs of the tool and how to easily debug your application using this incredible tool. In the next section, we designed a way to catch errors and display a friendly error interface to the user. We created a custom error boundary component for our functional component in the app.
Following that, we talked about the React developer tools. We discussed the Components tab and how you can use it to change props and states in a browser in real time. Then, we discussed profiling. Profiling is an excellent way of measuring how well a React application is performing.
Last but not least, we discussed VS Code’s debugging capabilities. You learned how to debug without leaving our lightweight but heavily packed VS Code.
I will introduce you to different ways you can style React components in the next chapter. We will practice some basic Cascading Style Sheets (CSS) as well. In Chapters 8 and 9, we will continue to explore more advanced React concepts, such as Hooks, authentication in React, Redux, etc.
Until now, we have learned about JavaScript, React, debugging, and more. You learned how to create an app with multiple components and how to manage state and props. While building apps, we added some styles. However, we never discussed styling in depth. We will discuss different ways of styling components and their pros and cons in this chapter. I will also introduce you to some tools that can help you choose styling for your React apps.
Cascading Style Sheets (CSS) is an essential part of any application. We cannot create a good-looking React application without CSS. It is crucial that your app looks good, not just okay, but great. There is no point in having a superfunctional app if it is unsightly.
Let’s inspect some basic styling concepts in this chapter. There are many ways you can style a React app. This chapter will not guide you through styling your React app using CSS. Instead, it gives you an overview of different methods and best practices to present your app.
We will discuss the CSS-in-JS pattern, which puts the styling in JavaScript (JS) itself. During our discussion, we will examine one of the component elements of the just-food project. We will learn how to use Styled Components in our React components and then explore further into CSS and how we use them in our applications.
Next, we will discuss the shortcomings of CSS and how we can overcome those. Finally, we will go over Sassy CSS (SCSS). We will cover the advanced features that SCSS brings with it.
You will learn about CSS modules and how they can address the global scoping issue that plain CSS faces. Then, this will be illustrated with an example from the project just-food. We will then update our app’s styling using CSS modules. We will discuss some useful tools that can help improve the way you develop and design React apps. Last but not least, we’ll explore how to make your application mobile-friendly, and I’ll introduce you to a new React Hook.
By the end of this chapter, you will understand the different ways to style React apps and the choices to make.
CSS-in-JS is an approach where we create CSS using JS and define it in the JS file itself instead of having an external CSS file. This method may have larger performance effects and look untidy. You will get to know why this is the case as we go through this section. However, this approach provides an advantage of allowing you to use expressions while defining styles within JS. Additionally, it can be a convenient way to create something for quick testing or similar purposes.
Keep a backup of App.js before you change it in the sections “CSS-in-JS” and “Styled Components.” When we start the “CSS” section, you can restore this file back. CSS-in-JS and Styled Components files are available in separate folders under the Chapter 7 section of the GitHub repo (https://github.com/Apress/Just_React).
Let’s use the top button from the just-food project as an example. We used that button to toggle between the Order Food and Menu Availability sections. The button uses a class called toggle button. When we use inline styling, we do not need that class. Rather, we can refer to the style within the JS file.
The attribute names must be in camel case when you apply styles inline. For example, we use the attribute background-color in a CSS class, but here, we used backgroundColor instead.
You should see the same appearance if you view the app in a browser now. The only difference would be the button background color, which we made intentionally. We just changed the styling to CSS-in-JS rather than using a CSS class.
Styled Components is a library built in for styling React apps. They built it based on CSS-in-JS. So it is basically a tool to use the CSS-in-JS type of styling. Its syntax is somewhat tricky. Let us replace our previous CSS-in-JS code by using a styled component.
It uses the same structure as a class in a CSS file. The only difference is that it requires a prefix styled. Additionally, we need to specify what type of element is to follow. For example, for a button, we add the prefix styled.button, and for a div, we would add styled.div.
After you run npm start, check if the app looks as it did previously. If you inspect using the F12 key, you will notice that it generated the button’s class name randomly. This is because the styled component generates a unique class name.
In comparison with plain CSS-in-JS, the advantage of Styled Components is that we can reuse them easily, because they create a component-based style. In addition, the classes will be unique, which will avoid the global scoping issue. We will discuss the global scoping issue in the next section.
Additionally, you can provide the styles in CSS format instead of adding a camel case style for each. As an example, you can use the CSS attribute background-color itself rather than using backgroundColor.
Now, revert back App.js as it was before the start of this section. Let us move on to the next section.
CSS describes how elements should be displayed on a browser. Let us take the example of our just-food app. How did we style this app? We used CSS. Let me demonstrate by taking the App component as an example.
If you open the just-food project and open App.js, you will observe the class ulApp assigned to the <ul> tag. We defined this class ulApp in App.css, which we already imported into App.js. We assigned it the <ul> tag using the className attribute.
So adding style using a CSS file takes three steps.
This way, we can define all the classes for the App component in App.css and assign to any element as needed. If we want to, we can create different CSS classes for different components.
We use this model throughout our book because it is simple to use and easy to understand, especially for small applications. There are some disadvantages for larger applications, including the fact that the CSS files may become large and it will be difficult to maintain or clean them up later. In addition, naming the class for each element will be challenging.
This would set all h1 headings in the application to blue. This shows how CSS’s global nature can be dangerous if we don’t pay attention to it. However, the global nature of CSS is one of its greatest strengths too. The global scope of CSS provides consistency to the websites and apps.
Imagine that you have around 10–20 CSS files. When you are naming a class, you must think if you gave the same name in another CSS file. If you do, that might override the style of another element. It can be extremely difficult to track down these definitions in larger applications.
I will explain this with an example from our just-food app. We will put the same class names in App.css and FoodOrder.css.

Different class names
The heading Chicken Burger appears as intended on top. We defined a class selFoodTitle for it in FoodOrder.css. Also, press F12 to check the class and its styles in the DevTools.
Consider a scenario where you forgot you had a class name subTitle in App.css and put the same class in FoodOrder.css.

Global scope issue with same class names
Here, both subTitle classes apply to the heading Chicken Burger. As the App component is a parent component, its CSS files will obviously get loaded into the child components. Technically, the Foods component is embedded in the App component. Therefore, the Foods component loads both classes and applies a mixed style. This is not what we wanted. This is the global scope issue with CSS. We need to be careful while naming the classes; they cannot be the same as what we defined before. This can be one of the major drawbacks of styling with CSS.
Another factor to be aware of is that child elements will always inherit the styles from the classes of their parents unless we specify otherwise. For example, in the App component, the li elements inherit padding and font size from the class of ul (ulApp). It was necessary to define the liApp class for li elements and provide padding-bottom to override the parent’s style there.
This section’s goal was to introduce you to CSS. We also outlined some of the troubles you may run into while styling with CSS. Next, let’s discuss SCSS before we get to CSS modules.
Sassy CSS (SCSS) is another way to style React components. SCSS refers to a modern syntax of a language called Syntactically Awesome Style Sheets (SASS). SASS is a language that is compiled into CSS. It is a language built on top of CSS. Besides having all the features of CSS, SCSS has some additional features.
Previously, we had defined this in the CSS file as the .toggleButton class. If you want to add another button inside the div, you don’t have to define a class name for each one. Instead, you can use this nested method. This is also an advantage of SCSS over plain CSS.
Furthermore, SCSS supports mathematical calculations. For example, I set a variable $fullWidth to 100 and set the width of the App class as ($fullwidth*2/5)*1%; and the left margin as ($fullwidth/2)*1%;. This means the width would be 40% and the left margin 50%. Therefore, it gives the same style as the App.css file.
In this way, you can refer to only FoodOrder.scss in the FoodOrder.js file and reuse the classes from App.scss. Similarly, you can import styles from third-party libraries such as Fluent UI, Bootstrap, etc. into an SCSS file.
We talked about how SCSS has more features such as nesting, variables, importing, math, etc. than plain CSS. However, it has the same disadvantages as using a plain CSS. Files can grow very large, and maintenance will be difficult.
The global scope issue still exists. Whenever you define a class, you need to think if it affects any other place. Let’s look at how we can overcome this problem by using CSS modules.
You can write classes that are scoped locally using CSS modules. CSS modules will autogenerate a unique class name. We can solve the global scope problem using CSS modules. CSS modules are extremely useful in React applications. This is the same as a plain CSS file, but the extension is module.css. Let me explain what CSS modules are again by using our app. We will fix the issue with the Chicken Burger title overlapping with the image that we encountered earlier.

Elements with plain CSS classes
It displayed each class name with the same name as we defined it.
This is how we import the CSS module file. The appStyles object contains the styles from the App.module.css file. You can name it whatever you want. As a convention, put styles at the end. I called it appStyles. This object contains all the classes that we defined in App.module.css.
So here we fetch the class names from the imported appStyles object.

CSS module–generated classes
You have the same look and feel, while at the same time, you have unique names for each class. You can spot a prefix, which is the component name, and a random generated suffix for each class name.

CSS module resolving the global scope issue
Because of the App component having unique classes, its classes will not mix up with its child components. With CSS modules, you do not have to worry about other classes while naming your CSS classes.
We can create SCSS modules in the same way as CSS modules. I prefer CSS modules over plain CSS, SCSS, SCSS modules, inline styling, CSS-in-JS, or Styled Components. All methods have their own advantages and disadvantages.
In the next section, we’ll examine a few third-party libraries and tools that can help you set up a good-looking UI quickly while creating React apps.
You can visit the GitHub repository to view the project code at any time during the learning. You can access the repository via the book’s product page, https://github.com/Apress/Just_React. The just-food project with CSS module implementation for all components is located under Chapter 7 ➤ Projects. You can refer to individual component code and also download or clone the entire project. After cloning, run npm install from the project folder to install all the required node modules before running the code.
The online code editor CodeSandbox is a very useful tool for you to quickly set up your React app. You can create your own React coding sandbox using this tool.

Sandbox templates

React CodeSandbox
This tool will be very handy for development.
Material UI (MUI) is a library of advanced components, which can style React applications quickly. You can visit https://mui.com for details on the installation, examples, different components, etc. There are so many options available.

MUI components

MUI components – CodeSandbox
In this way, you can try out different components and different styles using MUI and CodeSandbox to simulate them.
Within this chapter, we focused on desktop/laptop styling of React apps. Nowadays, most traffic for a website comes from mobile devices, making it important that your app is mobile-ready. Responsive design is an approach where we design our web pages in such a way that they adapt based on the device. In this section, we will look at the basics of responsive design. As usual, we will illustrate this with our just-food project. In this example, we will only focus on the home page, the App component.
Keep a backup of App.js before you change it in this section and then restore it back after the section. We will continue to use this project in Chapter 9 to illustrate authentication. At that time, we will use the code prior to this section as we don’t require responsive code there to keep the changes simple. In the GitHub repo (https://github.com/Apress/Just_React), you will see two copies of the just-food project: one before the responsive changes (just-food) and one with the responsive changes (just-food-responsive). We will use the former in Chapter 9.

Device toolbar
It is possible to select or unselect devices from the toolbar using the Edit link at the bottom. You can see our app isn’t mobile-friendly at this point. If you select iPad Air, at least the whole content on the page will be visible.
Let’s use this example to illustrate responsive design. In this example, we will focus on mobile and make our home page readable on mobile devices and desktops/laptops.
We will use a hook called useMediaQuery from an npm package react-responsive to implement responsive design. Media queries are one of the most popular methods for specifying distinct style according to screen size. The react-responsive package makes it easy to implement media queries in a React app.
When using the hook useMediaQuery, the isLapOrDesktop variable returns true if the screen size is greater than or equal to 1224px. Likewise, isMobile returns true if the screen size is less than or equal to 480px.
Now, we have the CSS classes available for desktop and mobile devices.

Responsive design
This is just an example of how you can implement a responsive design. I just created some basic CSS and have added no additional styling to make the app look great. You can always try to improve the styling for practice. You can implement responsive design for other components as well. As I mentioned before, while developing larger applications, it is ideal to have different components and CSS modules for mobile, tablet, and desktop/laptop devices. Then, we can use useMediaQuery to implement responsive design, like we did here.
When you close the device toolbar and refresh the browser, it will still work as before and open in the browser without breaking the view. This means now the app is adapting to the environment in which it is rendered. This is the concept of responsive design.
All the code of this section is available in the GitHub repo (https://github.com/Apress/Just-React). The entire code of App.js and App.css is available under Chapter 7 ➤ Listings, and the project is under Chapter 7 ➤ Projects ➤ just-react-responsive.
This chapter dealt with styling. Much like the previous chapters, this chapter also based most of its learning on our just-food React app. We began by learning about CSS-in-JS and its uses. Then we discussed Styled Components before moving on to learn how CSS works. There was a section to discuss some potential drawbacks of CSS when it comes to developing React applications.
After discussing the global scoping issue, we moved on to implementing SCSS-based styling. We briefly discussed several features of SCSS. Our next discussion was about CSS modules. We implemented CSS modules into just-food app components. In addition, we have discussed how CSS modules can overcome the global scoping issue. We talked about CodeSandbox and Material UI; we saw how these tools can be very helpful during the development phase of React apps. Lastly, we have discussed responsive design and seen how to implement it with the help of the react-responsive package.
In this chapter, we discussed the pros and cons of the different styling methods. I do not mean the chapter to make recommendations on which method you should use for your React app, but to shed light on how a React app reacts to different styling methods. According to my experience, CSS modules work better with React. However, always choose the best method based on your app. For example, a React app with nested elements may benefit more from SCSS modules, based on how comfortable you are with debugging SCSS styles.
In the next chapter, let us talk about one of React’s most exciting features, Hooks! We have already learned about Hooks in our previous chapters. We have used the useState hook many times. However, in Chapter 8, let us hook more into Hooks and try to build few custom Hooks!
The last two chapters covered debugging and styling React apps. In this chapter, we will continue learning React concepts from where we left off in Chapter 5. This chapter is about React Hooks. You already learned about Hooks from the previous chapters. We will dive deeper into Hooks in this chapter, and I can assure you it is going to be an interesting read. Hooks are the engine of modern React development.
We will begin by examining a class component’s lifecycle. After transforming it into a functional component, we will look at how Hooks can add state to it. We will discuss the state Hook and how it is used to manage the state in functional components. You will learn more about the effect the Hook and how it functions to emulate lifecycle events in functional components.
We will discuss refs in React and how important it is to not manipulate the Document Object Model (DOM). I will introduce you to the useRef hook, and then we will look at the useReducer Hook. We will learn complex state management with this Hook.
Next, we will discuss useContext with an example. Then, we’ll move on to memorization techniques. We’ll discuss the higher-order component (HOC) React Memo and the two memory Hooks, useMemo and useCallback. A detailed example will show you how to use these three techniques. Before we move on to the last section on custom hooks, we will discuss the remaining hooks. By the end of this chapter, you will be a Hook master.
In the following sections, let us investigate the back story behind the birth of Hooks. To get there, we need to learn about class components and its lifecycle events.

Creating a new sandbox
Select React from the pop-up, and it will create App.js automatically. Create a new component, called Time. Right-click the src folder and create a file and name it Time.js. Copy Listing 8-1 into Time.js.
Code used in each listing is available in the book’s GitHub repository, https://github.com/Apress/Just_React. You can refer to it from the path Chapter 8 ➤ Projects ➤ respective folder name.
Here we display the current time in a label. To do that, we used a setInterval method that changes the time every 1000 milliseconds. We placed this setInterval method inside the event componentDidMount.
componentDidMount()is a React lifecycle method that runs when a component is rendered for the first time. It calls setInterval to set the state for the current time. When the state is set, it re-renders the component, and the screen gets updated with the current time. Because of the state update getting repeated every 1000 milliseconds, it always updates the time on the screen. We’ve also added a console log inside the componentDidMount method that prints the message that the Time component is mounted at the current time.
There is also a componentDidUpdate event here. Inside this method, we are logging a message to the console that the time is changing at the current time. The componentDidUpdate() fires immediately after every render of a component except the first one.
Last, we defined a componentWillUnmount() method, invoking which will log a message to the console that the Time component is going to be unmounted at the current time. The componentWillUnmount event gets invoked when the component is about to be removed from the DOM. When you click a button from a child component to go back to the parent component, the child component unmounts. Just before that unmount, componentWillUnmount gets fired.
Let us inspect the code inside App.js. We defined a state variable open and set its value to true by default. In the return statement, we display the Time component only if the variable open is true. To close the time display, we have a button Close Time, which sets the variable open to false. The screen displays the button only when the variable open is true, which means when the time is visible. We wrapped both elements in a fragment.
As a result, by default, the browser renders the Time component, and the Time Closed display is not visible. When we click the button, it reverses.
During initial rendering of the App component, it mounts the Time component. This triggers componentDidMount. After mounting it, the time keeps updating, which triggers componentDidUpdate. Upon clicking the Close Time button, the Time component will be unmounted and trigger componentWillUnmount before unmounting. This summarizes the lifecycle events of the Time component.
Visualize this using CodeSandbox. Refresh the browser screen. You will see the message that the Time component is mounted at the current time. Keep the time running for some time. This will keep logging the message Time is changing to the console.

React component lifecycle
So we have seen how lifecycle methods work within a React class component. You can see that the Time is changing message got logged 250 times in around 4 minutes. This is because componentDidUpdate gets called every time the component is re-rendered. After the time display has been closed, you must refresh the screen for it to be displayed once again. This will restart the lifecycle.
There is a warning at the bottom regarding state update on an unmounted component. This is because the time interval is still running on the Time component while it is unmounted. This causes continuous state updates. We will fix this issue when we convert this to a functional component and use Hooks in the following section. Ignore it for now.
React creates a new instance of the Time component when it is called by the App component, during initial render:
This invokes the Time component’s constructor and renders the component for the first time:
This causes componentDidMount to be triggered, and the time updates. Note that componentDidMount only gets triggered on the initial render:
When we click the Close Time button, it will set the state variable open to false. This will trigger componentWillUnmount(), and the TimeInstance will be unmounted. As a result, the time is no longer displayed on the screen. This ends the lifecycle of the TimeInstance:
In React, it renders this function component by calling App(props). If we don’t specify any props, the arguments will be empty. If React needs to re-render this component, it will call App(props) again. This component does not have lifecycle events like a class component does, so it is impossible to manage the state. We cannot have a timer that is continuously changing on this component like we did in the previous section.
Let us redesign the App and Time components as function components, so that we can explore what we can and cannot accomplish in these components. Create a new React sandbox, or you can just update the code in the existing sandbox. Choose React from the pop-up, and it will create App.js by default. Create Time.js as we did before and copy Listing 8-3 into it.
In CodeSandbox, you can sign up for free and save your work, as we will use it for all the examples in this chapter. To create a new sandbox, if you are inside one already, click File and New Sandbox, as shown in Figure 8-1 at the start of the chapter.
This App component imports the Time component. The variable open is true by default, so the Time component and button Close Time will render by default. If we set the variable open to false, the heading Time display closed will appear. Refer to Figure 8-3. We defined a function closeTime to set the variable open to false. When we click the button, this function is called and sets the variable to false.
The time does not change at all. This is because we call the Time component once and we do not have the option to call it repeatedly inside the App component.
Close Time does not function. When we click the Close Time button, the time display does not close. It calls the function closeTime and sets the variable open to false. You can see this on the console shown in Figure 8-3. Everything is fine so far, but the App component does not re-render because there is no state change. The App component renders based on the previous value of the variable open.
We will refer to these issues in the following section as issue 1 and issue 2.

React functional components
What we observe here is that function components are simple. They accept props and can return JSX. If you have only render methods on your components, you can create them as function components. But what if you have state management on your components as well, like the preceding example?
The only way to achieve this functionality was using class components. Here comes Hooks, the concept that was born to address this issue. Hooks enable function components to hook into React state and lifecycle.
Before React 16.8, React developers were habituated to coding with class components and lifecycle methods. One fine day, it became clear that building React apps with class components wasn’t the way forward. As the developers adapted to the new hero in town, React Hooks, their life became a lot easier. Hooks made the code more readable and reusable. Thanks to Hooks, now we can manage the state without writing a class.
In Chapter 4, we saw an example of Hooks being used by converting a class component to a function component. Let’s enable these Time and App components to have state and lifecycle events by utilizing Hooks.
You can use either regular or arrow function syntax while defining function components. In most of the following examples, I used regular function syntax.
You must include this declaration within the component. You might wonder why you can’t put the declaration of the state variable outside of the component declaration. I’ll explain. A state variable stores data about the component. The component re-renders when the state changes. Before a re-render can be triggered, React needs to see the state and decide what has changed. Thus, we must declare state within a component for React to be able to control it.

Return values of useState
Now, the variable open will have the value true, and the setOpen will contain the function. The variable open is now considered a Boolean type and has the value true. If you call setOpen(false), it sets the value of open to false.

useState and re-render
Now we have resolved issue 2 mentioned in the preceding section. The useState Hook updated the variable’s state, which caused the component to re-render. This thus closed the time display. The state Hook preserves the value of the state variable during re-render. When we called setOpen(false), it set the value of the variable to false, and the component re-rendered. During re-render, it checks the value of open, sees it as false, and then displays the elements accordingly. If you refresh the browser screen, it will display the time again because the value of open again initializes as true.
Now, we can switch between time display and the closed message with the help of the state Hook. This resolves issue 2 that we mentioned in the preceding section. Issue 1 remains unresolved, because the time is not changing. We are only seeing fixed time until refresh. Let us fix that in the next section when we learn the effect Hook.
Using the componentDidMount lifecycle event of the class component, we could display constantly changing time. In a function component, we cannot access lifecycle events, but we can hook into them. The Hook useEffect handles side effects in functional components, as the name implies.
The Hooks were imported into the Time component here. We defined a state variable to hold current time. We added the Hook useEffect, within which we are logging a message to the console. In addition, we defined the setInterval method inside useEffect, which updates the current time continuously.
Now if you update the code and refresh the browser screen, you see that the time is continuously changing. From the console logs, you can see that the useEffect gets fired when the initial render occurs.

useEffect

useEffect calls on every render
Even though the time gets updated, this is not a clean way to use the effect Hook here. The setInterval periodically updates the time. Thus, we should call setInterval only once during the initial render. Therefore, we want useEffect to get triggered during this initial render only.

useEffect only on initial render
The only change is that we passed an empty array as a second argument to have the useEffect call only on initial render. This works just like the componentDidMount in a class component. We simulated the behavior of the ComponentDidMount event by using the effect Hook.
Here’s how it works. The second argument that we are passing to useEffect is basically a dependency. If you specify a dependency array, the useEffect will run only if there is a change in the dependency array values. During the first render, the array is empty, and useEffect runs. When the component re-renders, the array is again empty, so there is no change, and the effect will not run. During the second re-render, there is still no change in array values. This stops the effect from running during any re-rendering.
This empty array will never update, so the effect will not be called again. This is how passing an empty array as a dependency makes useEffect only run on the initial render. With this, we have achieved the same result in a function component as in the class component.
Now, let’s try to implement a function to display the current time in the console when the time display is closed, as we did by using the ComponentWillUnmount event in the class component. In essence, implementing that will give us a cleanup function to use before the Time component unmounts.
I updated the log message in the initial render to display the current component time. Also, I added a return statement inside useEffect. In any callback function, the return is being called on the unmount event. When we return a function inside useEffect, it will run just before the component is unmounted.

useEffect during unmount

Cleanup before unmount
So, we implemented the cleanup function using the effect Hook. In a class component, we could have done it using the componentWillUnmount event. By using the Hooks useState and useEffect in our functional components, we have achieved the same result as when using a class component. The code is much simpler and cleaner than when using a class component.
Note that we can use multiple useEffect blocks inside a single component, either with an empty array or by referencing specific props. You can handle initial mount by passing an empty array as a dependency. Also, you can set a code block to trigger during only a specific prop update by adding more useEffect blocks.
You can see an example of using multiple useEffect blocks in Chapter 5 (section “Props Drilling Issue”). There we added two useEffect blocks in the EnrolList component to handle edit functionality: one with all the props as a dependency and the second one with only the selected student id prop as a dependency.
Use refs only when necessary. The core concept of React is its declarative programming style. In React, we update data on the browser by changing state and re-rendering the components. In declarative programming, we do not interact with the DOM. The user interface (UI) gets updated when we change state. When we use refs in React, we go against this rule and access the DOM directly. We refer to refs as escape hatches in React.
Rarely, it will be necessary to access DOM properties directly. In these cases, we can use refs. A common example is when we want to put focus on an element. Let’s walk through the process in an example to learn more about refs and the Hook useRef.
Let us create an input form with three fields – State, City, and Address – and a button. We want the focus to be on the field State by default. Once we filled in City and State, we can click the button, which fills the Address field content with the City, State format. After that, the user has the option to edit the Address field content. Our requirement is to have the focus on the Address field once we click the button.
I named the variable for state as state. Please be aware of this and avoid confusion with our React state. I will rename the fields in future examples.
Let me explain the code for App.js. We created the form with three fields, State, City, and Address. When any of these fields changes, the value is set to the respective state variable using the handleInputChange function. We set the focus by default to the field State by using an attribute autofocus. We don’t need to use any refs for setting the focus in the initial render; instead, we can use the autofocus attribute.
Fill Address is a button. After you fill in State and City, if you click the button, it invokes the fillAddress function. The function sets the state variable address to the City, State format. This updates the Address field.
As of now, we do not access the DOM directly, and we did all screen changes using state management. There is a requirement that the focus needs to be set to the Address box when we click the button and fill the address. To do this, we must access the address element using a ref.

useRef usage
Note that we only used the ref to focus the Address field here. We can get the city and state values using refs instead of state. The code will be shorter if we do that. However, that is not the right way to do it. It will take down React’s declarative concept. Use refs only when necessary. In all other cases, update component data using state management.
We call a component controlled by its state a controlled component. If component data is handled by the DOM, we call it an uncontrolled component.
In this example, state management code occupies not a great deal of space in the component body. But what if we have ten input fields in the form? We must define state variables for each of the ten controls and manage state using useState. This would result in a large component code.
Let us now see if there is a solution for keeping the code concise. The preceding form, which we implemented, is having a simple functionality. The component file contains three state variables. We use the state Hook to manage state during input changes.
This component has two logical sections. One is the rendering part, where we create input fields to be rendered to the browser, and the second is the state management. As I mentioned previously, imagine what happens if there are many input controls in this form. The code will be messy and will be difficult to maintain and test if we create state variables for each of these and manage state using useState. The reducer Hook useReducer can deal with this. The useReducer hook handles complex state management.
As mentioned in a note in the preceding section, now I renamed the variables to fieldState, fieldCity, and fieldAddress, instead of having the previous names: state, city, and address. This has nothing to do with the reducer Hook. It is just to avoid confusion with React state and the variable name state.
Both the Hooks initiate the variable state with an initial value. With useState, the second variable setState is a function we can use to modify the state of the variable state. In the reducer Hook also, the second variable is a function, which is the dispatch function. This function is also used to update the state, but it is different. Let’s look at the difference in more detail.
You are free to use any names for state, dispatch, type, payload, or reducer. However, as per convention, we always use these names.

useReducer
As you can see, using the useReducer hook is extremely helpful for managing state in large complex applications.
React’s Context API offers a more convenient way of passing data between components. Implementing Context is a three-step process. You should create a context, provide it from a component, and consume it from any other component that needs it. The useContext hook provides a “Hook” way to consume a context.
Sending props from higher-level components to lower-level components is known as props drilling, as you learned in Chapter 5. Suppose you have three components, A, B, and C. Component A is the parent of component B, and component B is the parent of component C. You want to pass a prop from component A to component C. You need to pass it from A to B and then from B to C. This requires drilling a prop through component B unnecessarily. You can imagine what it would be like if your application is complex. Due to the large component tree, managing the application through props drilling will be extremely challenging.
With Context and the useContext hook, we can solve this problem. React Context enables data to be passed between components without drilling through middle components.
With the just-food project in Chapter 5, we have seen an example of how to use Context and useContext. We will create a similar app here, but a small one to demonstrate how the useContext Hook works.
Let us create an app called Food Shop. We will have three components in this app. The root component, App, will have a header and a button. The header will show whether the shop is open or close. By clicking the button, you can switch between the texts open and close. The App component also contains a Menu component. The Menu component will feature a static list of food items. It also contains an Order component. You display an Order button in the Order component. Clicking it displays an alert. When the shop is open, you want to display the Order button. This occurs when the header in the App component says the shop is open. When it is close, the Order button in the Order component should not be visible. Now let’s implement this.
In this Order component, we just have a button with a text Order. The button will be visible only if the value of the prop open is true. Upon clicking this button, it calls the orderFood function, and this function just displays an alert.
In the Menu component, we just have a static list of food items. In addition, this component calls the Order component with the prop isOpen.
We pass the value of this state variable, shopOpen, to the Menu component as prop.
Next, we have the function openOrCloseShop. This function switches the values of the header and button text variables. This function is called during the button click.

Food Shop app – passing props
The app works as expected. However, we passed the prop isOpen from App to Menu and from there to the Order component. The purpose of the prop isOpen is to set the visibility for the Order button, which is in the Order component. However, we are drilling the prop through the Menu component, which does not need this prop at all. We can avoid this drilling by using Context.
Let us redesign the component using Context.
This step creates a context using the method createContext. We created the context and stored it in the variable shopContext. We are exporting this in a variable, so that we can use it in our Order component.
This means that all our JSX elements are now included inside of the preceding tag. In this context provider, we put the value as shopOpen. Therefore, whether the shop is open or close is now provided in this context.
Now we’ve imported the useContext hook. Besides that, we imported the shopContext from the App component.
Execute the app, and you can see that it works as before, but this time without drilling props through the Menu component. The shop matter is handled directly between App and Order. The Menu component doesn’t have to act as a middle entity.

Food Shop app – passing context
You can view entire component codes of each section under the Chapter 8 folder of the GitHub repo (https://github.com/Apress/Just_React).
Let’s now discuss two more Hooks, useCallback and useMemo. But before we do that, let’s first try to understand the concept of memorization in React.
Memorization is a technique where we remember something and use that later rather than retrieving it again. For example, by now you are already memorizing how to set a state variable in React using the state Hook. You don’t need to refer to any references anymore. You know it off the top of your head.
We have defined an array memorizedData. In the first call to addNumbers(8,9), it checks if there is a value with the key (8,9) in the memorizedData array. As this is the first call, there will be no value, so the result will be undefined. It calculates the result using a+b and stores it in the memorizedData array with the numbers (8,9) as keys. The next time, when you call addNumbers(8,9), the function checks if there is a value with the key (8,9) in the memorizedData array. It finds a value matched to the key, which is 17, and returns it.
By doing so, the function never calculates the same numbers again. As it is a simple calculation, it won’t make a difference here. But if the math is very complex and takes a lot of processor time, you might save a significant amount of time by not performing the calculation for the same arguments every time, because the answer won’t change. Memorization generally works on this principle.
Memorization is no different in React. In React, we can memorize a component using a higher-order component (HOC) called React Memo. An HOC wraps a component and returns a new component. React Memo wraps around a component and memorizes it. It then uses this information later and avoids unnecessary rendering.
To see memorization in action in React, let’s build an app for a library in which they want to know the number of ways they can arrange books on a particular shelf. The user wants to enter a shelf name and print it out. They also want to enter the number of books and ways they can arrange the books on the shelf.
This component Shelf is a simple component that accepts a parameter shelfName and just prints out that name with a message.
This component calculates the number of combinations from the count of books provided. It uses the mathematical concept of factorials to calculate the number of arrangements. For example, if the number of books is 4, it returns 4*3*2*1=24. Even if the number of books is slightly more, for example, even if it is 10 books, the calculations can get expensive. We added a logging to the console also to see how often this component re-renders. The re-rendering of this component can affect performance, as it will repeat expensive calculations.
The App component returns a form with two input fields. One is the Shelf field where the user can enter a shelf name. As soon as we enter a shelf name, it will display it on the following label. This is because of the rendering of the Shelf component, which we added in the label with the shelf name as an argument.
The second field is where the user can enter the number of books. Upon entering this number, the component Combinations renders. The Combinations component calculates the number of possible arrangements using the factorial concept. When the book count is greater than zero, the screen displays the Combinations component. We can view the returned number of arrangements on the label.

Rendering the component

Unnecessary rendering of the component
South Block is now updated as the new shelf name. However, the Combinations component got rendered eight times. This means it calculated the factorial for 20 eight times, which is unnecessary and expensive and affects performance. Even if the count of books does not change, it re-renders the Combinations component whenever you change the shelf name. However, it needs to render only if the count of books changes.

React Memo
The following example shows how a React Memo component can wrap other components to memorize and to only render if the props change.
Note that we do not have to memorize everything. The purpose of Memo is to optimize performance. So we use Memo only if it can improve the performance of an app. You can use Profiler to check an app’s performance like we discussed in Chapter 6. Always run profiling before and after using Memo to see if it was worth memorizing.
In the next section, let’s get back to the “Hooks” track. We will focus on two other memorization techniques, the Hooks useMemo and useCallback. We will use the same example to demonstrate them. Note that all three have different usages. You will see the difference once we go over the two Hooks. But the same rule applies to Memo, useMemo, and useCallback. Use only if necessary to improve performance.
The React Memo HOC can memorize a component and prevent re-rendering if the component props have not changed. On the other hand, the useMemo() Hook can memorize a function output if the function dependencies have not changed. The useMemo() function calls a function and memorizes its output. The next time we call this function, it checks if the dependencies have changed. If they have not changed, it will return the previously memorized value. Otherwise, it will call the function again.

Re-rendering due to prop change
The reason is that we now have two properties for the Combinations component, which are the book count and shelf name. We already wrapped the Combinations component using React Memo, and there is no change in the countBooks property. Nevertheless, as the second prop shelfName changed, it re-rendered the component. As a result, it repeated the factorial calculation several times. We want to avoid this calculation if only the name changes; we want to do it only if the book count changes.

useMemo()
You can observe that now the calculations happen only twice. That is when you type the first digit 2 and when you type in 0 as the second digit to make it 20. The Combinations component is re-rendered eight times as before because of the name change. However, the factorial calculation won’t occur because there is no change in the book count. The useMemo() returns the memorized output if there is no change in the dependency countBooks. So, when the shelfName changes, it returns the memorized value, and when the countBooks changes, it recalculates the output and returns it. In this way, we can improve performance by memorizing expensive code executions with the useMemo() Hook.
useCallback is another memorization technique in React. It has the same syntax of useMemo. However, useCallback memorizes the function, whereas useMemo memorizes the value. In the preceding example, to retrieve the calculated value, we cannot use useCallback because it will return a function instead of the value we need.
As mentioned before, we use memory Hooks and React Memo only if they can significantly improve performance. We only need useCallback in rare scenarios, such as when a function call causes component re-renders. useMemo can be helpful in few scenarios like the preceding expensive calculation scenarios.
As you can see, now the Combinations component returns a button element along with the total number of combinations. The button calls a function checkSpace with a parameter space. It calculates the space based on a switch function, which is based on the number of books. We removed the prop shelfName as we no longer need to display the shelf name along with the combinations.
That completes the changes in App.js. When you type in the book count, the component Combinations gets called with the book count and the handleClick function. Within the Combinations component, it sets the callback prop checkSpace with the value of the space. This invokes the handleClick method inside the App component, and the screen displays the space along with the number of arrangements.

Re-rendering because of callbacks

Function equality check
Even though itemClick and itemClick2 are same, comparing them returns false. In JS, a function equals only that function. Functions are reference types, so two different functions are stored in different places in memory even if they are same. So, between each rendering of a component, a function will be different.
Whenever you update the shelf name, the state variable shelfName gets updated, and the App component re-renders, which causes the Combinations component and Shelf component to re-render. The React.memo checks if the props have changed before rendering the Combinations component. When checking, it will see that the book count has not changed, but the callback function prop checkSpace has changed. This is because of the preceding explanation, where JS treats each function differently during re-render, even though the function name and definition have not changed.

useCallback()
Here, the Hook useCallback memorizes the function handleClick. So React.memo does not see any changes in the prop checkSpace, preventing the Combinations component from re-rendering. Even if you click the Check Space button, the component will not re-render given that there is no change to the countBooks and handleClick(), which are the props passed. If you change the book count, the component re-renders because of the change in the first prop. This way, the useCallback Hook memorizes a function call between renders and avoids re-renders due to the function equality behavior.
As you can see from the preceding examples, React.memo is for memorizing a component. The useMemo Hook is used to memorize values, and useCallback is used to memorize functions. Using these techniques when you start developing an application is not recommended. Once you have developed the application or a large section of it, use Profiler to check for performance leaks. Next, identify the cause and use these techniques to fix it.
useImperativeHandle – We use useImperativeHandle with the useRef hook. For example, you can use this Hook for focusing an element inside a child component during a change in the parent component. Imagine the App component is having an input field called Name. You created a ref in the App component and forwarded that ref to a child component, Child1. For forwarding a ref, we can use an HOC called forwardRef. This forwarded ref in the Child1 component is assigned to an input field, Country, inside Child1. You want to focus on the Country field of the Child1 component when there is a change in Name, which is the input defined in the App component. By defining a useImperativeHandle hook in Child1 along with a callback prop, you can pass the focus from App to Child1 during the onChange event of the field Name. You may rarely use this Hook in practical scenarios, and, like the ref Hook, the use of this Hook will access the DOM directly.
useLayoutEffect – Using useLayoutEffect is like using useEffect, except it runs in parallel while the DOM is being rendered. The Hook is called before the browser displays the DOM changes. The useEffect is called only when the browser has finished painting changes to the screen. It is recommended to use useLayoutEffect only when useEffect is causing any blocking of the visuals, which is very rare.
useDebugValue – The useDebugValue hook can be useful when creating custom Hooks. You can use it to display logs in the React DevTools. You can substitute console.log statements with this Hook.
A custom hook is a JS function whose name starts with the word use. And a custom Hook may call other Hooks. Thus, if you develop a Hook, the name should start with use. You can identify a Hook with the prefix use. I believe use is the perfectly suitable prefix for Hooks because Hooks are extremely useful and a brilliant concept in modern React programming.
By implementing custom hooks, we can extract specific logic and reuse them in different parts of the app. Let’s put together a simple custom Hook for learning how to develop a custom Hook. Here, we will use the same example from earlier sections. We will create a Hook to calculate the factorial instead of doing the operation directly in the Combinations component.
We created the Hook useFactorial now. This hook accepts a number and returns its factorial. In addition, it is using the useMemo Hook as it involves expensive calculations. So, if this Hook is called a second time with the same number, it returns the result without re-calculating it.
Now, we have imported the custom hook useFactorial into this component. We can find out the number of ways for the books to be arranged using a single line of code. We also do not have to worry about memorization as the Hook handles it.
Here we do not need to import the useMemo Hook anymore. Also, as per the rules of Hooks, we cannot call Hooks from loops, conditions, nested functions, or callback functions. So we cannot call useFactorial() inside useMemo(). We call Hooks from custom Hooks, which we have done by calling useMemo() from the useFactorial custom Hook.

Custom Hook
We show here an example of how you can extract logic and create a custom hook. There are many community-built Hooks available to use. You can install the containing package with npm, and you may then reference the Hook in your app. It is possible to share your developed custom Hooks with the community so that other developers can reuse them. However, you may not want to use custom hooks at all as it is just encapsulation of a functionality. You can even achieve this by creating reusable functions and export them so that the other components can refer them. React Hooks enable you to hook into the React lifecycle and state, whereas a custom Hook won’t do that.
You can visit the GitHub repository to view the project code at the end of each chapter. You can access the repository via the book’s product page, https://github.com/Apress/Just-React. All the code sections used in this chapter are located under Chapter 8 ➤ Projects. Final code in each section is available under the respective folders, which are named with respective app and Hook names. Also, I added the name of the listings, which can be found under a folder.
Hooks, a vital part of modern React programming, took center stage in this chapter. We began learning by developing a deep understanding of the class component lifecycle. Following that, we learned how state Hook and effect Hook enabled functional components to Hook with lifecycle events. We learned details of state Hook and effect Hook through examples.
In the next section, we learned about the ref Hook, useRef. We talked about the concept of controlled components in React and the importance of making wise decisions about when to use the refs. Our next topic was the useReducer hook. We discussed how it can manage state and be extremely helpful in larger applications.
Next, we discussed React Context and the useContext hook. We have seen an example of how to consume component data by using the useContext Hook. Then we discussed how memorization techniques can improve the performance of a React app. We discussed how React.memo can memorize a component and avoid re-rendering it. With the same example, we discussed useMemo and useCallback Hooks and demonstrated how the three methods differ in their usage. We stressed the importance of using the performance hooks only when they can enhance performance. We created our own custom hook in the last section and explained about custom Hooks.
React Hooks emphasize on the importance of thinking in React exactly like other React concepts. We need to think carefully before choosing a specific Hook. Building an app in React relies more on your thinking and your actions, which are based on your knowledge, practice, and experience. It is impossible to build a React app by referring a piece of code from the Web. We need to think, rethink, ‘React’ and ‘React’.
In the next chapter, we will discuss how React handles communication with backend services. You will learn about authentication, Redux, etc. Let’s move on to next!
This chapter explores a few concepts that we haven’t discussed so far. These concepts are sometimes a requirement common to all frontend programming languages. The chapter discusses these concepts and how React can meet them. In previous chapters, you learned how React works as a frontend library. In this chapter, we will explore few interactions with backend services, such as an Application Programming Interface (API) or database.
We will begin by learning about routing in a React application. We will discuss different routing concepts and demonstrate the concept with a simple example. Then, we will move on to the authentication section, which makes up the major portion of this chapter. Authentication starts with an overview of Firebase, which is a Backend-as-a-Service (BaaS). We will set up an email password authentication in the just-food project using Firebase. You will learn how to interact with a backend database and authenticate users.
Next, we will discuss consumption of REST APIs in a React application. You will learn how to make Hypertext Transfer Protocol (HTTP) requests using GET and POST methods by using the Axios library. The last section of this chapter introduces you to Redux through an easy-to-understand example. By the end of this chapter, you will have a solid understanding of how React interacts with backend services and be able to create more complex React applications.
The term routing is one of the common terms used in programming. Routing is the process of redirecting a user to different pages based on a request or action. With routing, we can build single-page web applications that have navigation without having to refresh the page while navigating. As soon as a user clicks a link, the URL changes, and a new view is rendered on the page. We can implement routing in React using a library called React Router.
Let us create an app and set up routing to understand the concepts. Imagine that this application has three pages: the home page displays the food menu, the Order Food page allows you to order food, and the Contact Us page lets you contact the company. For each page, we will display a header with a different color.
Go to https://codesandbox.io and create a new React sandbox, as we did in the previous chapters. Install react-router-dom as a dependency from the left-hand side of Explorer. For a real-time application, use npm install react-router-dom from the VS Code terminal to install this.
In CodeSandbox, ensure that the dependency react-router-dom is installed. Once installed, you will be able to see the dependency under the Dependencies section. If you hover over a dependency, you can see a refresh icon. Click it to update a dependency to the latest version. This applies to all dependencies you install while using CodeSandbox.
We imported BrowserRouter, Route, Routes, and Link from react-router-dom. BrowserRouter is a type of Router component. react-router-dom provides HashRouter and BrowserRouter as routers for a desktop application. A Router component creates routes. We must add it at the root of our app to enable routing, so we wrap our root component in a router. We imported BrowserRouter and wrapped our App component in it.
We added code for a menu items list using <ul> and <li> tags and defined some basic styling for these elements. Within each <li> tag, we added a Link. The Link component of React Router provides navigation. For example, we defined /Food as the to attribute of the Order Food Link. When we click the link, the URL becomes localhost/Food.
In the last section, we defined Routes. Routes is a route matching component that matches the path with the current URL. You click the Order Food link; it redirects you to the URL localhost/Food. The <Routes> component checks the URL and discovers that it matches the path /Food. As a result, it renders the Food component. In a similar way, all other components get rendered based on the clicked link.
You may find <Switch> was used as a route matcher in older versions. Note that Switch will not work with the latest version of react-dom-router. Always use <Routes> as the route matcher.

React app with routing
In this example, I clicked the Contact Us link, and you can see that the URL has been updated to /Contact, and it has rendered the Contact component.
Only the navigated component renders when you use routing to navigate between components. Routes enable users to switch between views within a single page without requiring a browser refresh.
This section aims to provide a basic understanding of routing in React. React Router can be a large topic and is beyond the scope of this chapter. Check out the official React Router documentation at https://reactrouter.com/docs/en/v6 to explore more on this subject.
The authentication and authorization processes are crucial to managing access of an application. Even though they go hand in hand and are often carried out sequentially, authentication and authorization differ in their purpose and execution. To understand this, let’s look at Facebook as an example. To log in to Facebook, you enter a username and password. By using your username, you are claiming your identity. Passwords serve as proof that you are the person you claim to be. This is known as authentication. You entered the correct password and logged in. There are posts from a specific group you wish to view. However, you are unable to see that because you are not part of the group. It’s called authorization. Authorization determines whether a user has access to specific data. Authentication and authorization are fundamental to any application.
To implement authentication and authorization in React, we can use third-party backend services. There are many choices available. Using Firebase, we will demonstrate access management in the just-food React project. Firebase is a Backend-as-a-Service (Baas). Firebase offers developers a variety of tools and services. With it, it’s easy to authenticate using passwords; phone numbers; social networks like Google, Facebook, and Twitter; and more.
Let’s go back to our just-food project, which we created during Chapter 5. We will implement authentication in this app. Every user will need to sign in to order food from Just Food Online Shop. Once logged in, the Order Food page will appear. If the logged-in user is admin, the Availability Check button should be visible. Only the admin user can access the Menu Availability page. With the button, the admin user can check the menu availability and access the Order Food page. Other users should only have access to the Order Food page.
Review Chapter 5 to recap the just-food project implementation, since we will build authentication on top of the same app here. To view the latest code of the just-food project, visit the Chapter 7 ➤ Projects path of the GitHub repository (https://github.com/Apress/Just_React). You can also download or clone the entire project. After cloning, run npm install from the project folder to install all the required node modules before running the code.
Let’s get started. We will go through the process step-by-step to digest each part of the implementation.
Step 1: Firebase configuration.
Let’s first set up Firebase. Go to https://firebase.google.com, click “Get started,” and log in with your Google account. Once you have signed in, click “Create a project.” Name your project and click “Create.” I named it as just-food, the same name as our React project.

Firebase – setting up authentication methods

Firebase – creating a database

Firebase – setting up the app

Firebase – app config
You can see from Figure 9-5 that if you click the “Config” radio button, you can see the firebaseConfig variable, which we are going to use in step 2, when we are using VS Code to configure authentication in our just-food application.
Step 2: Set up the app to communicate with Firebase.
After copying the code, replace the const variable firebaseConfig with your project config from Firebase. Refer to Figure 9-5.
Step 3: Authentication component.
Next, let us look at the useEffect function. If it finds a user, it redirects to the /app URL using navigate. We will define the routing for the App component at a later step in the index.js file. We will set it on the path /app.
The CompleteSignInOrSignUp method calls the respective Firebase function we defined in firebase.js. If isNewUser is true, it calls the signUp function; otherwise, it calls the signIn function.
Step 4: Define routing.
So here we defined routes for the Auth component and App component. By default, the Auth component loads. When a user is successfully authenticated, the navigate("/app") gets called from the Auth component. So the URL changes to localhost:3000/app. As a result, the App component loads as per the routing we defined here.
Step 4: App component changes.
The next line created a state variable to store a user’s email address and a Boolean state variable to distinguish between the admin user and other users:
We get the user object using the auth, and then we set the user email to the state variable userEmail. This email we can use to display at the top of the screen. Then we inserted a condition to see if the user’s email equals admin@justfood.com. We set the isAdmin variable to true if the condition is true.
When the user is empty, it navigates to the path /, which loads the Auth component, and the Sign In form will appear. We added a dependency array so the useEffect will only execute when it’s needed, just like it is in the Auth component.
This ensures that the app displays the message Signed in as user email when a user logs in.
This ensures that only admin users can see the Availability Check button and hence the Menu Availability page.
The user gets logged out because of this call to the logOut function of Firebase. Because of the navigation defined in useEffect, the user gets redirected to the Sign In form again.

Sign Up form

Admin interface

Customer interface
As you are not the admin user, you do not have access to the Menu Availability page. Sign out now and then sign in with the admin account. This time, you will use the default Sign In form. You do not have to sign up again because you already have an account. The Availability Check button should now be visible, and clicking it will direct you to the Menu Availability page. In this way, we have authenticated and authorized the user. If you return to Firebase and check the authentication and database sections, you can see the details of all the users who have signed up.
Firebase features built-in validations. For example, if you try to sign up the same user email again, for example, john.smith9@justfood.com, it will tell you that the email already exists. If you try to sign up with a wrong password, the wrong password alert will appear.

Sign In form and authentication errors
We can, of course, convert these error messages to a friendly user interface. But for this section, we focused on learning how to implement a basic email password authentication and authorization in React.
We can build more complicated validation and security rules using Firebase. We can have the forgot password option and different authentication options such as logging with Google, Facebook, etc. using Firebase. There are also many backend services available to implement authentication like Auth0. I will leave it for you to explore further.
So far, we talked about how to authenticate a React app using a backend service. In this section, we discuss how to communicate with a backend API in React. An API is a connection through which two applications can communicate with each other. APIs enable communication between the front and back ends of an application. We can use APIs to consume data from frontend apps built using technologies like React, Angular, etc.
Imagine you have data hosted on a server. You want to display this data in a React app and also want to update this data from the app. There are many libraries available for this purpose in React. Let’s explore Axios here. Axios is a library that we can use to create HTTP requests from the browser.
Let’s see an example. We will create an app that allows us to enter an employee’s name and role. The app will then display the employee’s name, role, and id and the creation time. In addition, the app displays the manager’s name. Using https://reqres.in, we will mock API requests.
Using this method, we make an HTTP POST request to reqres.in. We are posting name and role in JSON format. It creates the user and returns the result with a data object containing name, role, id, and creation time. We then format the data and display it on the label.

Sending HTTP requests from React
For POST, we used https://reqres.in/api/users as the endpoint with a JSON as input. For GET, we used https://reqres.in/api/users/2 as the endpoint. We used the Axios package to make these HTTP requests. We looked at a simple example for creating and retrieving data from an API. You can also update and delete data. You can also set authentication headers while making an HTTP request using Axios or any other library.
Redux is a library that is used for state management in frontend applications. Redux is not specific to React. You can use it with any other library or framework such as Angular, Vue, or plain JavaScript.
Store: The store holds the global state for an app. In a similar way to what we did earlier with Context API, we can wrap the root component of an app in a provider tag with the store as a prop. This allows all the app components to access the store.
Action: An action object is the gateway to the store. Any component in the app can access the store through this object. Action objects have two properties – type and payload – where type describes the action to be taken and payload contains the data to be changed.
Reducer: The reducer function receives the current state and action. It then changes the state according to the action and returns the new state.
Dispatch: The dispatch method of a Redux store is the one that carries the action object. To update the state, we call the dispatch method with the action object as the parameter.
The action, dispatch, and reducer concepts are the same as what we learned with the useReducer Hook. For a recap, refer to Chapter 8, section “useReducer.” For a recap of Context API and the provider component, refer to Chapter 5, section React Context.
Redux requires two packages: redux, which is the main Redux library for state management, and react-redux, which connects the Redux store with React components.
If the action type is addNewTask, we append the payload to the array and then return the updated state. By default, we set the reducer to return the current state. That means, on initial render, it returns the initial state of the array. Initially, the array contains an item with task name Meeting at 9.
Now let’s look at the JSX elements inside the return function. We have an input text box where the user can enter the task name and then click a button. The button text is Add. Below that, we have a menu list, <ul> tag, which displays the added tasks.
So we have the list populated with one item initially, which is Meeting at 9.
During the button click, it calls the function handleClick. Inside handleClick, we call the dispatch function with action object as the argument. The action object contains type as addNewTask and the entered task name as the payload.
The dispatch function calls the reducer, which updates the state. We defined the reducer function in index.js. As the App component is subscribed to the store updates, the prop tasks gets updated with the new state, thus updating the to-do menu list.

Redux with React
Redux is a large topic. In this section, we limited our discussion to just understanding what Redux is using a simple example. This will help you get started with Redux. Since we have the React Hooks and Context API now, you won’t need Redux in most apps. Still, it can be very useful for managing the state in complex applications. Furthermore, it provides extensive debugging features with its DevTools and the ability to use middleware.
You can visit the GitHub repository to view the project code, via the book’s product page, https://github.com/Apress/Just_React. The code for the apps created for routing, HTTP requests, and Redux is located under Chapter 9 ➤ Projects. You can also access the just-food project with added authentication under Chapter 9 ➤ Projects.
In this chapter, our primary focus was on how React interacts with backend services. Before moving on there, you learned about routing and how to set up navigation in a multi-page React app.
The next section examined authentication in detail. We began by configuring Firebase and setting up a communication channel between Firebase and our just-food app. Then, we implemented the sign-in, sign-up, and sign-out components. We improved our just-food app by implementing authentication.
We then discussed how a React app could consume REST APIs. We created an application that would retrieve and create data using HTTP requests and Axios. We created dummy APIs using reqres.in. Last, I explained the working of Redux using an example.
This chapter was an attempt to explain the above-mentioned concepts in a simple and easy way so that you can grasp and learn and build on top of it. Are we moving to the end phases of React learning? Definitely not. We are just nearing the end of our book – Just React. But not before chatting about some new reactions! The last chapter will cover the exciting new features of React 18.
In our final chapter, we discuss the new features of React 18. The primary focus of React 18 is on the concurrency features and performance improvements. React 18 was released in March 2022. Most of the dependency packages, including the Redux library, have already made React 18–compatible versions available. All the projects in this book are using React 18.
We will begin by discussing the new Root API and the new way of rendering in React 18. We will then move on to discussing the concurrent behavior of the new React. I will introduce you to the concurrent features with an emphasis on transition and Streaming server-side rendering (SSR). In the next section, we will review automatic batching using an example app. We will conclude the chapter with an overview of the updated strict mode and the new Hooks available with React 18.
This chapter will bring you up to date with the latest React features and prepare you to upgrade your existing projects.

Using React 17

Upgrading to React 18
As you can see, the app is running with no issues. Now try to upgrade to React 18 by switching back the versions of the dependency packages to 18.0. A warning will appear on the console.
Hit the refresh icon on the CodeSandbox browser. The warning has disappeared now. Compare Listings 10-1 and 10-2. You can see that the new Root API uses ReactDOM.createRoot as opposed to the ReactDOM.render in the old API. Previously, it was necessary to pass the root element to the render method in the old API, but no longer. The new API provides access to React 18’s concurrent features.
From React 18 onward, concurrency will become a habit of React. By upgrading to React 18 and the new Root API, we became equipped with the concurrent features of React.
Let me try to explain the concept of currency with a real-world example. Imagine a scenario where you are going to a busy restaurant for dinner and you need to finish some work for the day. You have two options. Option 1 is you can finish your meal, come home, and finish the work. This may delay your sleep. Option 2 would be to order the food and begin the work while you wait. If the food is ready before you finish the work, stop it, and then continue it once you get home. This helps you save some time and sleep a bit earlier.
In this situation, you have two tasks. Task 1 is to have dinner, and task 2 is to do the work. Task 1 is your priority, but you want to complete task 2 also on the same day. With option 1, you can complete the tasks in sequence. Using option 2, you can start task 2 while task 1 is in progress. When task 1 needs your attention, such as when the food is on your table, you can interrupt task 2 and finish task 1. After you have finished task 1, which is when you return home, you can continue task 2 from where it left off and complete it. This way, you can save some time and sleep earlier.
So option 2 here is a concurrent execution of tasks. Until now, in React, we cannot interrupt a transaction once it is started. As an example, imagine when you click a button, two state updates are made to elements A and B. React batches these state updates together. It updates the Document Object Model (DOM) once. Therefore, the user interface (UI) is rendered together for both elements. It is impossible to tell React to render element A later on. With React 18, this has changed. It introduces concurrent features. The concurrent rendering improves application performance. In the next section, let us look at the concurrent features of React 18.
By default, React renders a consistent user interface (UI). The UI renders together for all the elements. But sometimes it might be helpful to introduce an inconsistency by rendering elements at different times. Using concurrent rendering, we can bring in this inconsistent UI rendering. React 18 introduces the concurrent features of transition and deferring.
UI updates can be classified into two categories: urgent and non-urgent. Sometimes, the urgent ones are light, and the non-urgent ones are heavy. The non-urgent ones can be put on hold while the urgent ones can go ahead. This makes the app more responsive and efficient. We can make this possible by using an API called startTransition. Non-urgent updates are called transitions.
Let me explain by creating an example. We will create an app where the user can search for a keyword and it returns approx. 10000 results. We will set random text to return 10000 random results. Copy the following code to the App.js of the app that we created before.
In this app, we have a text box where the user can enter a keyword. Once the user enters it, we are setting the state so that the text appears in the text box. Afterward, we are doing a dummy search by creating an array of 10000 random results. In each result, there are two paragraphs containing 100 words each. Finally, it sets the results value as a menu list to the state variable result. We display this menu list next to the search text box.
Imagine you want to search for “React.” When you type in “R,” you cannot see the search results immediately, since it will take time to finish looping through 10000 items. You are okay with that, because you only want to see the results after you typed in the whole word “React” and you don’t mind waiting a few seconds after that to see the results.
However, you want to see the characters as and when you type them in, and that is not happening because of React’s consistent UI behavior. Results menu list rendering isn’t complete, so it doesn’t render the text box either. The heavy and non-urgent UI update here is the search results. The light and the urgent UI update is displaying the typed-in characters in the text box. Despite the light nature of the urgent update, the wait on the heavy UI update slows it down.
React will interrupt this update when the user types the next character, and it will render the portion of the UI that has already been updated. Here, it will display the updated text box value since its state has already been updated.
If you go back to the screen and type “React” or any other word, you can see the characters as you type. After a few seconds of wait, the results will appear. What if we want to let the user know that the search results are loading during the wait?
That’s all. Now you can see the loading message until the search results appear. Once the results appear, the message disappears. The isPending variable will be false until the results load, and it will be true once the results complete loading.
You can view the entire App component code with transition under Chapter 10 ➤ Projects ➤ 4. Transition folder of the GitHub repo (https://github.com/Apress/Just_React).
Suspense-based server-side rendering (SSR) is one of the key features of React 18, which can greatly improve performance of applications.
With client-side rendering (CSR) on a single-page application (SPA), to view anything on the page, we will need to wait till the whole JavaScript (JS) completes its execution on the browser. Until then, the page will be blank. For large-sized applications, the rendering takes longer, resulting in a bad user experience.
Server-side rendering is a technique where we generate HTML from React components from the server side and send it to the client. So the users will not have to wait for the client-side JavaScript to be executed as they can already see the HTML sent from the server.
Prior to React 18, in server-side rendering, it compiles the whole React app to HTML and then sends it to the client. For a large-sized application, this again causes performance issues because of the server response size and its rendering on the client side.
You may have some components of the page that can be loaded later. The new Streaming SSR feature allows you to put those components inside a Suspense component. That means the server generates HTML for the priority components first and sends it to the client. This allows the browser client to display some HTML on the page while the work is still in progress for the suspended components.
After the server has sent the initial response, the client continues to receive updates from the SSR streams. Components that have been suspended in the process are rendered on the server and streamed to the client. The app can display HTML before all the functionality is ready, and this makes the app load faster.
We saw an example for Suspense in client-side rendering (CSR) in Chapter 5, section “React Lazy and Suspense.” Suspense works similarly in SSR. In SSR, the react-dom/server APIs used to implement Suspense-based SSR are renderToPipeableStream and renderToReadableStream.
As you use SSR, you will also need to know about React Hydration. Hydration is like rendering, but different. During render, we render components to an empty DOM. During hydrate, we will have the DOM already rendered. Then, we attach functionality, such as event listeners, to the already rendered HTML in the DOM. If you use SSR, the server will render your HTML page during the initial render, and you may need to add functionality to it. The hydrateRoot method is used to add event listeners to the already rendered HTML. With client-side rendering (CSR), we render everything together with the render method.
So here the container is expected to be present. The container needs to be rendered from the server side.
Here, we will not go into details about server-side rendering. The goal of this section is to provide an overview of how SSR has changed in React 18. We haven’t discussed SSR in this book so far. It wasn’t popular in React as there weren’t many advantages. However, with React 18 introducing Streaming SSR, SSR now became a great choice for some of the React applications.
Before React 18, hydration of the whole application begins only after the client fetches the whole page from the server and rendered it. As a result, the user could only interact with the page after the whole application had been hydrated. Therefore, the user must wait for the less important components of the page before being able to interact with another component. If these lesser urgent components were slow to load, this would have a significant impact on the user.
Let’s say you have an article page with an option to edit and give feedback on each article. The feedback component takes longer to load. The user wants to read and edit the article first and then add feedback. When we are using React 17 and older, the user must wait for all components to be rendered and then hydrated. It would be better if we could load the article component first and then the feedback.
When we use Streaming SSR, it allows hydration to happen step-by-step. The hydration first happens for the initially rendered components of the page. The user can then interact with those components. After the entire page has been hydrated, the user can interact with the full page.
In the preceding example, we can wrap the feedback component in a Suspense block. So we will have the article component rendered and hydrated first. Users can read and edit the article while the feedback loads. The feedback component can join a bit later. This is the efficiency brought in by Suspense-based Streaming SSR. This is one of the concurrent features of React 18.
Prior to React 18:
You must fetch everything before you can load anything.
You must load everything before you can hydrate anything.
You must hydrate everything before you can interact with anything.
React 18 Onward:
You can load something you wish before fetching everything.
You can hydrate what you loaded.
You can interact with what you hydrated.
Automatic batching is when React groups multiple state updates into a single re-render for better performance. State updates are batched together inside event handlers in React, even before React 18. For example, if you are making two or more state updates on a button click, the component gets re-rendered only once. We will create an app with a button and a span element next to it. When we click the button, the background color of the button should switch between two colors. Additionally, the span element should show how many times we clicked the button.
Set up a new sandbox in CodeSandbox. First, let us downgrade to React 17, as described in the first section. Update react and react-dom packages to 17.0.2 and copy Listing 10-1 to index.js because we need the old Root API code for React 17.
In this example, we have a button changing colors between light green and orange. Also, we have a span showing the number of times we changed the button color. In the useEffect method, we log the message The Component Rendered to the console. Note that we didn’t specify any dependency array to useEffect here since we need to call it after each re-render, not on first render. To skip the first render, we added a condition.

Batching state updates
Even when clicking the button multiple times, you can see that only one re-render takes place per button click. So this proves that React 17 has this automatic batching capability for event handlers.
What about other scenarios like setTimeOut or if we want to perform multiple state updates during a data retrieval from an API call like we did in Chapter 9 with Axios? Let us see an example with setTimeOut.

No batching during setTimeOut
In the older versions of React, it limited the batching capability only to event handlers. Upgrade the react and react-dom packages to React 18. Also update index.js code to reflect the new Root API. Refer to Listing 10-2 for the code reference.

Automatic batching in React 18
If you keep the screen for minutes, you will observe that the number of times the color changes matches exactly with the number of times the component re-renders.
Sometimes, one state update may depend on another, and we need to re-render the page for each update. Upgrading from React 17 projects, if these scenarios exist, may cause a code break. How can we fix this?
The answer from React 18 for that is flushSync API. flushSync prevents automatic batching. If we use flushSync in a specific state update, it will trigger a re-render for that update.

Flushing automatic batching
Use flushSync only in specific cases if it cannot be avoided. Otherwise, just let the amazing automatic batching feature stay.
As part of React 18, it introduces a new strict mode behavior. This helps find potential side effect problems with components. These problems can be more significant with the new concurrent features, and the updated strict mode helps solve that. Components mounted for the first time are unmounted and remounted. This restores the previous state on the second mount. The strict mode checks only run in development mode, so they will not affect production build. The strict mode, like fragments, renders no visible UI. You can see the App component wrapped in strict mode by default when you create a React 18 project.
Visit https://github.com/reactwg/react-18/discussions/19#:~:text=With%20the%20release%20of%20React,mount%20)%20for%20newly%20mounted%20components for detailed discussion on this subject.
useId: As we discussed before, there are changes to server-side rendering with React 18. The server sends priority HTML first based on how we set Suspense, and the hydration also happens in steps. In order to avoid hydration mismatches, we need to generate unique IDs on both the server and the client. The useId hook can be used for this.
useSyncExternalStore: React 18 introduces a potential issue called tearing. Tearing means that the UI shows different values for the same state because of the concurrent rendering. When we work with an external state management tool like the Redux store, the UI may show two different values for the same data. Tearing can occur when we wrap a store update with the startTransition method. The useSyncExternalStore hook eliminates this issue by forcing updates to the store to be synchronous. This Hook is recommended for any library that integrates with state external to React.
useInsertionEffect: CSS-in-JS libraries may generate new style rules that they intend to insert into <style> tags in the DOM. With React 18, these injections may cause issues because of the concurrent rendering since React interacts with the browser before the rendering process is complete. The useInsertionEffect resolves this problem. This hook runs concurrently with the DOM rendering and is called before the browser displays changes to the DOM. The Hook is used to insert global DOM nodes such as <style>. The useInsertionEffect is intended for CSS-in-JS libraries, such as Styled Components. So you may rarely use this Hook in real-time projects.
You can visit the GitHub repository to view the project code at the end of each chapter. You can access the repository via the book’s product page, https://github.com/Apress/Just_React. All the code sections used in this chapter are located under Chapter 10 ➤ Projects.
The chapter’s focus was on the new features of React 18, which is mainly a performance upgrade to React. We learned how React 18 differs from older versions and how to upgrade. In this chapter, we learned about the new Root API and discussed the new rendering method. We talked about concurrency and the new concurrent features React 18 brings to the table. Next, we covered the useTransition hook and startTransition API with a detailed example. Then, we discussed the new server-side rendering feature of React 18. Last, we discussed automatic batching and how it can improve the performance of React applications.
So I’m just going to stop reacting for now. Thank you! We discussed nearly all the features of React with examples. Hope you enjoyed learning with this book and that it can be a useful reference for you while developing React applications. You can contact me at Just React Q&A (https://jrhn22.wordpress.com) if you have any questions on this book or on React. Just leave a comment, and I will be more than happy to respond.
No doubt, React will dominate the present and future of web development. It is simple and efficient. As you keep on reacting, I’m sure you’ll have something to take away from this book! Just React, and keep learning React the React way!