Home JS ReactJS 7 Fascinating Reasons People Like React.js

7 Fascinating Reasons People Like React.js

0

Hello, and welcome to the React.js: Getting Started series, from onurdesk. All the examples we do in this series should work on any React version greater than 16.8. In this series, we’re covering the fundamentals of the React.js library. 

No previous React.js experience is required to take this series. We will be starting from level 0. But you do need some JavaScript experience first. 

To be specific about that need, you need to know how to define and use JavaScript variables, holding scalar values, objects, and rays. You need to know how to define and use functions and classes. You need to know the basics of working with loops and conditionals. I have some resources here for you if you don’t feel completely comfortable with the basics of the JavaScript language.

 

I recommend that you check them out first. If you’re coming to React with some previous knowledge of JavaScript, but you have not used the modern features of the language that were added in the past few years, that is not a problem. This series has a module to introduce these features. 

In that series module, I’ll cover things like arrow functions, restructuring, REST, spread operators, classes, and more. We will not be using advanced JavaScript. A basic knowledge of the language will be enough for you to survive this series. But, you’re likely to run into problems that are related to the language syntax rather than the React.js API. 

I’ve written an article on jsComplete about the common problems learners usually face when working with the React.js library. Scan through this article quick and keep it for your reference when you run into a problem while taking this series. Also remember that you can always ask for help in the Comment tab available in this series page. 

Onurdesk mentors watch these comment forums, but please be as descriptive as you can when you ask a question. Share your code, list any errors you’re getting, and share a screenshot if you can. And when sharing your code, don’t paste it here. This comment tool is not good for that. 

Why React.js?

I’m a big fan of starting with why? 

So before you dive in and write your first React component, let me make sure that you know why committing to learning React is a very good thing that you’re doing. If you’ve already formed your opinion about React, you can skip this video. 

Let’s start with React’s official definition. It states that it is a JavaScript library for building user interfaces. It is important to understand the two different parts of this definition. React is a JavaScript library and not a framework. The words library and framework mean different things in different contexts, and this could be a point for or against React. 

What’s important to remember here is that React is small, and it’s not a complete solution. You will need to use other libraries with React to form solutions. React does not assume anything about the other parts in any full solution. It focuses on one thing, which is the second part of the definition, building user interfaces. A user interface is anything we put in front of users to have them interact with a machine. 

User interfaces are everywhere, from the simple buttons on a microwave to the dashboard of a space shuttle. If the device we’re trying to interface can understand JavaScript, we can use React to describe a user interface for it. Since web browsers understand JavaScript, we can use React to describe web user interfaces. I like to use the word describe here because that is what we basically do with React. We just tell React what we want, and it will build the actual user interfaces on our behalf in the web browser. 

Without React or similar libraries, we would need to manually build user interfaces with native web APIs in JavaScript, and that is not as easy. When you hear the statement that React is declarative, this is exactly what it means. We describe user interfaces with React and tell it what we want, not how to do it. 

React will take care of the how and translate our declarative descriptions, which we write in the React language to actual user interfaces in the browser. Of course, HTML itself is a declarative language, but with React, we get to be declarative for HTML interfaces that represent dynamic data, not just static content. Let’s go back to React being a library and not a framework, and let me answer this question. 

How exactly is not being a framework a good thing? Frameworks serve a great purpose, especially for young teams and startups. When working with a framework, many smart design decisions are already made for you, which gives you a clear path to focus on writing good application‑level logic. However, frameworks come with some disadvantages as well. 

For experienced developers working on large codebases, these disadvantages are sometimes a deal breaker. Let me name two of the important disadvantages about using a framework. Frameworks are not flexible, although some claim to be. Frameworks want you to code everything a certain way. If you try to deviate from that way, the framework usually ends up fighting you about it. 

Frameworks are also large and full of features, and that makes them hard to customize for specialized cases. If you need to use only a small piece of a framework, you usually have to include the whole thing. This is changing today, but it is still not ideal. Some frameworks are going modular, which I think is great, but I am a big fan of the pure UNIX philosophy to write programs that do one thing and do it well. 

And React follows this philosophy because it is a small library that focuses on just one thing, enabling developers to declaratively describe their user interfaces and model the state of these interfaces. 

Here’s a summary of the reasons why I think React gained this massive popularity. Working with the DOM API is hard. React basically gives developers the ability to work with a virtual browser that is friendlier than the real browser. 

When React was first released, I remember there was a lot of buzz around the performance of its virtual DOM, which we will talk about shortly. The virtual DOM performance is certainly a nice plus, but I think what developers like more about this is the fact that they wouldn’t need to deal with the DOM API. Some people don’t like this second point, but you’ll often hear that React is just JavaScript. 

What that means is that there is a very small React API to learn, and after that, your JavaScript skills are what make you a better React developer. This is a big advantage over libraries with bigger APIs. Learning React pays off big time for iOS and Android mobile applications as well. React Native allows you to use your same React skills to build native mobile applications. You can even share some logic between your web iOS and Android applications. 

The React team at Facebook tests all improvements and new features that get introduced to React right there on facebook.com, which increases the trust in the library among the community. It is rare to see big and serious bugs in React releases because they only get released after thorough production testing at Facebook. Most importantly, remember the one thing that React does exceptionally well. 

React established a new language between developers and browsers that allowed developers to declaratively describe stateful user interfaces. This means instead of coming up with steps for the transactions on their interfaces, developers just describe the interfaces in terms of a final state, like a function. 

When transactions happen to that state, React takes care of updating the user interfaces based on that. If someone asked you to give one reason why React is worth learning, this last one is the one. If you need to convince someone about React, you can send them to this article, which summarizes what we covered in this video. However, to keep the course short, I’ll stop babbling about the why and get you started on the what and the how next.

React’s Basic Concepts

React has three simple and fundamental concepts that you need to understand. The first concept is its components. With React, we describe user interfaces using components. If the term components sounds scary to you, you can really think of components as just functions. In fact, simple React components are actually just vanilla JavaScript functions, as we’ll see in the next video. 

In any programming language, we invoke functions with some input, and they give us some output in return. We can reuse functions as needed and compose bigger functions from smaller ones. React components are exactly the same. They receive certain input objects, and they output a description of a user interface. We can reuse a single component in multiple user interfaces, and components can contain other components. 

However, you don’t really invoke a React component. You just use it in your HTML as if it was just a regular HTML element. Also, unlike pure functions, a React component can have a private state to hold any data that may change over the lifecycle of the component. This ties to the second concept about React, it’s nature of reactive updates. React’s name is a simple explanation for this concept. When the state of a React component, the input, changes, the user interface it represents, the output, changes as well. 

This change in the description of the user interface has to be reflected in the device we are working with. In a browser, we need to regenerate the HTML views in the DOM tree. With React, we don’t need to worry about how to reflect these changes or even manage when to take changes to the browser. React will simply react to the changes in a component’s state and automatically update the parts of the DOM that need to be updated. The third concept about React is its virtual representation of views in memory. 

Okay, this might sound a bit weird, but to build HTML web applications with React, we don’t write HTML at all. We use JavaScript to generate HTML. Let me tell you why. When your web application receives just the data from the server in the background with AJAX, you need something more than HTML to work with that data, and you have two options. You can use an enhanced HTML template that has loops and conditionals, or you can rely on the power of JavaScript itself to generate the HTML from the data. 

Both approaches have advantages and disadvantages. React embraces the latter one and eliminates the extra step needed to parse and enhance the HTML template. One big advantage for this HTML in JavaScript approach is how it enables React to keep and use a virtual representation of HTML views in memory, which is commonly known as the virtual DOM, or the tree reconciliation algorithm. React uses the virtual DOM to compare versions of the UI in memory before it acts on them. I’ll show you the practical value of that once we’re comfortable with the basic syntax of React. 

Let’s go back to the concept of the component. A React component can be one of two types. It can be either a function component or a class component. Both types can be stateful and have side effects, or they can be purely presentational. You should learn them both, but prefer to use function components over class components because they’re really much simpler. Class components, however, are a bit more powerful. In this course, I’ll use a mix of these two types so that we can learn them both. 

Both types can be compared to regular functions when it comes to their contract. They use a set of props and state as their input, and they output what looks like HTML, but is really a special JavaScript syntax called JSX. The props input is an explicit one. It is similar to the list of attributes an HTML element can have. The state input is an internal one, but is really the more interesting one because of how React uses it to auto‑reflect changes in the browser. These two input objects have one important difference. 

Within a component, the state object can be changed while the props object represents fixed values. Props are immutable. Components can only change their internal state, not their properties. This is a core idea to understand in React, and I’ll have many examples for you to bring it home. Okay, let’s talk about this syntax that looks like HTML, but is not really HTML. 

Here’s a full example. This is a simple React class component without any input, so no props or state, and with a simple h1 in a div output. On the left side, the component is written in the special JSX syntax. Remember how I said we don’t write HTML at all in React, and instead we use the React API to generate our views? In a way, this JSX syntax that you see on the left is the compromise to that rule. It makes our task of using the React API as close as possible to writing HTML, but it is not HTML. It simply gets compiled to the pure JavaScript calls that you see here on the right. 

These React.createElement calls that you see on the right are what we ship to browsers. They are the JavaScript representation of this component’s DOM, and they are what React can efficiently translate into actual DOM operations to be performed by the browser. This is important to understand, but how about we stop with the theory and slides and write some code to understand all these concepts better.

Your First React Component

Let’s implement this simple React component, a button with a numeric label, and clicking that button increments it’s numeric label to count how many times the button was clicked. Ready to do that? Don’t worry, we’ll take it one step at a time. First, let me tell you about this interface that you see here. 

Before you can create a React application, you’ll need to do some environment configurations, and that might be a bit overwhelming for someone who is just starting to explore. Before we go that route, we’ll use this interface that I especially created for this course. It will help you learn the React way without the complexities of configuring a ton of tools to have a React environment. This playground is a good first step for quickly exploring React, but it stops being useful once the size of your application grows. 

This is why the last module of this course will be about configuring your own React environment. But until we’re ready for that, we’ll use this playground. This is the point in the course where you need to start doing things with me and not just watch me. Go to jscomplete.com/playground and follow along with what I do. I kept this interface as simple as possible. You have an editor and a display. You type in some JavaScript code in the editor, for example, Math.random(), and you press Ctrl+Enter and your could will be executed and its results displayed on the right. 

Just like a simple REPL, run, eval, print, loop, that you can use to test quick JavaScript expressions. To show more things in the display, you can use the HTML element with the ID of mountNode. You can grab a reference to this element using document.getElementById and specify mountNode as the ID. This is a DOM API call to select the display element. And once you do that, anything you put inside this mountNode HTML element will be displayed to the right. 

The more important thing about this playground is that the latest version of both React and ReactDOM are already preloaded here. In addition, the playground understands the JSX syntax. And it will also work with the modern JavaScript features, which we will be using with React. Guess what I used to build this playground? React, of course. You can actually tell that this playground is written in React, looking at this little icon here in my browser. 

This icon is coming from the React DevTools extension, which is something you should install right away, by the way. So if you don’t have this icon in your browser, pause the video right here and go Google for React DevTools extension and add the extension to your browser. Once the extension is active, relaunch the jscomplete playground and make sure the icon is showing up here. 

The React DevTools extension allows us to inspect and interact with any React application on any website. Let’s inspect the jscomplete playground while we’re here. Open your browser’s DevTools. There should now be a new tab for React. This has been added by the React DevTools extension. You’ll see that the extension is showing up two nodes here. The weird one is the main component for the jscomplete playground React app. 

You don’t see normal component names here because the code is minified, but you can still see the structure of the app and you can see the properties and state of every component in the DOM tree, and you can interact with everything here. For example, this editor area here can be resized by dragging the separator. And this UI state is managed with React. If you can find the component responsible for that, you’ll see how there is a state element that gets changed when the separator is dragged. You can even change this state directly from the DevTools and trigger the resize based on the new value. 

How cool is that? Take a moment and familiarize yourself with this extension. It is going to be a great asset for you when you start writing React applications. Every video in this course will start with a URL at jsdrops.com. That will take you to the starting point of that video. This way you can start from the exact point where I am. And if you’re coding along in the video and you code did not work as expected at the end of the video, you can simply compare your code to the code available when you go to the next jsdrops URL in sequence. Here is the first URL. 

If you go to jsdrops.com/rgs1.1, rgs is for React Getting Started, you should see the exact code that I now have on the screen. Make sure that works for you. When this code is executed, you should see a Hello React line in the display. Let me go over what is going on here. We have a simple React function component named Hello. It returns a div. This component has no input. It’s also a peer component, no state here. To display a React component in a browser, we need to instruct the ReactDOM library on how to do that. 

The function designed to do that is ReactDOM.render, which takes in two arguments. The first is the component to render, in our case it is the Hello component. Look how I used it here as if it was just another DOM element with a self closing tag. The second argument to the ReactDOM.render function is the DOM element in the browser where we wish the React component to show up. In this playground, we’re using the mountNode display element. 

If we were to do this in a regular React environment, this element has to exist in the already rendered HTML before this code. You can think of this element as the entry point for React. We’re telling React to take over this element and render all of the content within it. Time for another interview question. Explain what exactly is going on here on line 2. How are we writing HTML inside a JavaScript function? And why is this working and not throwing an error? This is not valid JavaScript. If you copy this code and try to execute it anywhere JavaScript can be executed, it will throw on error for sure. 

However, in the playground, the code works fine because the playground is equipped with a special JavaScript extension named JSX. That should be the gist of your answer. This line is not HTML, it is JSX. It will not be executed by the browser. It will be executed by the JSX extension and compiled to something else, something the browser can understand. This absolutely means that what this browser is currently executing is not what you see on the screen. The playground is using a special compiler named Babel to convert JSX into React API calls. You can see exactly what Babel is doing to our JSX, if you go to the Babel REPL here under try it out. 

Make sure this React preset is selected, and paste in here the JSX value that we’re testing in the playground. Babel compiles that into a call to the createElement function in the React top level API. That’s it. That’s the magic of JSX. You write what looks like HTML and Babel converts into React API calls. So in the good example we have here, the browser is not really executing this. Instead, it’s executing the following, React.createElement, and this takes many arguments. The first argument is the element to be created, in this case, a div. The second argument is any attributes this element will have, the div element has no attributes. 

And the third argument is the child of that div element, in our case, it’s just the string Hello React! Let me add a few more here to make sure this is working, and go ahead and execute this. And check it out, it is working. You see this line in React applications, but the browser is really executing this line instead. And this is true here as well, this line is also JSX. In this case, the conversion would be React.createElement, and it is a hello element here, this is not an HTML element, this is a React element. And it also doesn’t have any attributes and it doesn’t have any children. 

So this is the equivalent line in this case, and this will work as well. While you can totally use React this way, without JSX, it would be a lot harder to code and maintain. So let’s stick with JSX. Let’s now update this code to make it into the button counter example that I showed you at the beginning of this video. Instead of a Hello component, let’s name our component Button, uppercase B button. You’ll have to do this change to the function name and where we used it here in the JSX line, Button. Instead of returning a div, let’s make it return a button HTML element, lowercase button here. 

Start that buttons label as TEST. Ctrl+Enter to execute, and you should see a button with a label of TEST. Now I intentionally rendered a button component and the button element in this example. This is to make you aware that the capitalization here is not optional. React has some rules here. A component name has to start with an uppercase letter, because if you don’t do that, React will think you meant an HTML element. 

For example, if we named our React component lowercase b button and tried to render that here, React will just render an empty button element here, and it will really not use this function up here at all. This is a beginner mistake. Always name your components with an uppercase first letter. This rendered button here is not interactive yet. To make it so, we’ll need to introduce some state to this component. We’ll use the simple and powerful React hooks to do that in the next video.

Your First React Hook

Continuing with what we started in the previous video, the current code is available under this URL, and our component currently renders a stateless button. We now need to make the button increment a counter every time it’s clicked. We need a state object. To use a state object, react has a special function named useState. This is also globally available here in the playground. So we’re going to be invoking this function. 

This useState function is going to return two items for us. The first item is a state object, and the second item is a function to change that state object. The state object can be of any time you wish it to be. It could be a string, a number, or an array, or anything else. For this use case, we need it to be a number. I’m going to name this state object counter and name its updater function setCounter. The syntax you need here might look a bit weird, but since JavaScript functions can only return a single value, the useState function returns an array with exactly the two elements here. 

To make this work, we need a variable‑defining keyword before this syntax. I’m going to use const. This special syntax here is using JavaScript destructuring feature to capture these two variables in one line. It’s not magic or anything; useState returns an array with two elements, and in here we’re destructuring these two elements into variables in our Button component. The argument to useState is the initial value for the state element, counter in our case. Since we want that counter to be a number, we’ll set that to 0. 

To use the two new variables that we introduced, let me tell you a nice little thing about JSX. It supports displaying dynamic expressions if you place them within curly braces anywhere inside JSX. So if I make the button’s label into curly braces, and inside these curly braces put any JavaScript expression I want, I’ll use Math.random, and execute the code, the button will have random value every time I render this component. So to use this new state element, all we have to do is put the counter variable within curly braces and make that the label of the button element. The button will now be rendered with a label of 0. 

This is the same 0 that’s coming from the initial value we specified for useState. So any value initialized here will show up as the button’s label, but we’ll keep it as 0. Now to use the setCounter updater function, every time we click on this button, we need to introduce an event handler. This is going to look similar to the way we can do this with the DOM API. 

We define an onClick attribute on the button element. This onClick attribute is also case sensitive. It has to be camelCase like this. And unlike the DOM version of the onClick, which receives a string, this react onClick attribute receives a function reference. So you always specify that inside curly braces as well. In here, we’re going to specify a function reference. 

Let me create a dummy function here, function. I’m going to name it logRandom, and we’ll make this function console.log(Math.random). Very simple. To use this function as the onClick event handler, we pass in here the functions reference, its name, just like this. To see the console.log messages, we need to bring up the browser’s console here. And after executing this code, every time I now click on that button, the console will print a random value. 

Note that when we passed in the logRandom function here, we did not invoke the function. This will not work. You just need to pass in the pointer to the function. You can also inline the function definition right here inside the curly braces. So, basically, you paste in the function definition, and this will work as well. We can make this more concise by using the new arrow function syntax, which can fit in a single line here, () =>, and then the body of the function directly after that. This highlighted part is an inline arrow function definition. We’re not invoking the function here. 

We’re defining it and passing this new reference to the onClick prop. This will work as well. So now that we saw how to wire an onClick event, what we need to do to make the counter count is to use the setCounter updater function that we got from useState. So instead of console logging a random value here, I’m going to use setCounter, invoke that function, and the argument to setCounter will become the new value of counter here. So if we pass in counter+1 as the argument just like this and execute this code, then every time the onClick event is triggered now, the counter will be incremented, and you’ll see the button behaving as we wanted it to. 

This useState function is called a hook in the react world. It is similar to a mix‑in or a module, but it is a stateful one that hooks this simple component into a state. What I need you to notice here is that to reflect the new value of the counter variable in the browser here, we did nothing. 

We just managed the state of the counter value. React is automatically updating the browser for us thanks to its reactive nature. We did not implement any transactions on this UI. We implemented the transactions on a JavaScript counter object in memory. Our UI implementation was basically telling React that we want the label of the button to always reflect the value of that counter object. We didn’t do any DOM updates. 

React did. You’re going to need a few more examples to appreciate this power. So let’s add some more features to this basic example. Let’s make our UI show many buttons and make all the buttons increment a single counter. But before we do that, let me give you a quick challenge. Instead of a simple counter, change this component to start the button with a label of 5, then double that value on each click. Go ahead and try to make this simple change, and you can see my solution under this URL.

Your First One-way Data Flow

In the previous video, we made a simple stateful Button component that renders an HTML button element and increments its numeric label when that button element is clicked. We introduced the useState React hook to manage a counter state. Let’s improve this component. First, don’t use long lines like this.

 They’re hard to read. So let me format this return value to make it more readable. There we go. Note how I used parentheses here, not curly braces. We’re not returning an object here. We’re returning a function call, remember, a React.createElement function call. Second Improvement. Instead of an inline function here, let’s create an official click handler function. 

 This new function has to be defined inside the Button component because it needs access to the counter and setCounter variables. You can use any name here, but it’s commonly named handleClick. We can just paste the code we had inline before here as the body of this function. And in the onClick attribute here, we pass a reference to handleClick. Make sure this is all good and the button is still incriminating. So far, we’ve only worked with one component. Let’s add more. Let’s split our one Button component into two. 

 We’ll keep the Button component to be just the incrementer, and let’s add a new Display component, which is going to just display the value of the counter. This new Display component is going to be a pure presentational one. It will not have a state of its own. That’s normal. Not every React component has to have a stateful hook. So to create a new component, we define a function named Display, and we’ll make it return some HTML element. For now, let me just put a placeholder div in here and execute. 

 Notice that this new Display component did not show up because I have not included it in the rendered element yet. I just defined it. Let’s include it. So remember to include a component, we need to use it like that. However, you can’t just add it here as an adjacent sibling to the Button element. This will not work. Question, why does that not work? And the answer is because each one of these elements get translated into a function call. 

 You have few options here to fix this problem. First, you can render an array of elements here and insert into that array as many React elements as you wish. This will work. This is usually a good solution when all the elements you’re rendering are coming from the same component in a dynamic way. It’s not ideal for the case we’re doing here. The other option is to make these two React elements the children of another React element. 

 For example, we can just enclose them in a div, create a div element, then render the Button and the Display inside this div element. The React API supports this. In fact, React has a special object. If you need to enclose multiple elements like this without introducing a new div parent, you can use React.Fragment. This will do exactly the same thing that the div did, but no new DOM parent will be introduced. This case is so common in React that the JSX extension has a shortcut for it. Instead of typing React.

 Fragment, you can just have an empty tag. This empty tag, if supported in the environment, will get compiled to the React.Fragment version. For the case that we’re doing here, I think a div here is okay, so I’m going to keep that. Question, what can we do to make this better? 

 And the answer is we should really extract this code into its own component. This new component can have any name, but you can just use App here. Go ahead and try to create this app component on your own. Make it return this DOM and use it in the ReactDOM.render call instead of what we have. We take the section, create a new function, name it App, make this function return the exact DOM tree that we have down under. 

 And then in here, instead of all that, we can just render the App component just like that. Since we’re going to display the counter’s value in the new Display component, we no longer need to show the counter’s value as the label of this button. Instead, I’m going to change the label to just +1. Now we need to display the counter value as the message in the Display component. But we have a problem. We actually have two problems. 

 The first problem is that the counter is currently a state element in the Button component, and we need to access it in the Display component, which is a sibling of the Button component in the current tree. So this is not going to work. The state in a React component can be accessed only by that component itself and no one else. To make this counter state accessible to both sibling components, we need to lift it one level up and put it in their parent component, which is the App component that we just introduced. 

 We just move this useState line down to the App component right here. I’ll initialize the counter with a different value here to make sure things are working. The logic of this handleClick function will need to change. We will come back to that in a minute. Let’s just comment it out for now. Now that we have the counter state element in the App compartment, which is the parent of the Display component, we can flow some data from the parent to the child. In this case, we need to flow the value of the counter state into the Display component, which brings us to the mighty props object. We haven’t really used it yet, so let me tell you about it. 

 To pass a prop to a component, you specify an attribute here, just like in HTML. You can name the props of the component anything you want. For example, I’ll make the Display component to receive a prop named message, and the value of that message is the counter variable that’s coming from the useState hook. The Display component can now use its props object, which is the argument to the function here, and it’s usually named props. You don’t really have to name it props, but that’s the convention. 

 All function components receive this object even when they have no attributes. So the Button component is currently receiving its props object, and that object so far has been empty. Because a component can receive many attributes, this props object will have a key value pair for each attribute. This means to access the message prop and place its value within the display div, we do curly braces and use props.message. 

 Let me test that real quick, and we have an error, handleClick is not defined because we’ve used it here and commented it out here. So let me just put an empty function here to get things working, and here we go. A counter value of 42 is now getting displayed. This is coming from the Display component. And what we did here is called the one‑way flow of data. Parent components can flow their data down to children components. Parent components can also flow down behavior to their children, which is what we need to do next. In the App component, since the counter state is here now, we need a function on this level to handle updating this state. 

 Let’s name this function incrementCounter. The logic for this function is actually the exact same logic that we had before in the handleClick function in the Button component. So we can just move it in here. This new function is going to update the App component’s counter state to increment the counter value using the previous counter value. The onClick handler in the Button component now has to change. We want it to execute the incrementCounter function that’s in the App component, but a component can only access its own functions. So to make the Button component able to invoke the incrementCounter function in the App component, we can pass a reference to incrementCounter to the Button component as a prop. 

 Yes, props can hold functions as well, not just data. Functions are just objects in JavaScript, and you can pass any object value as a prop. We can name this new prop anything. I’ll name it onClickFunction and pass it a value of incrementCounter, which is the reference to the function we defined in the App component. We can use this new pass down behavior directly in the onClick value. It will be a prop on this component, so we can access it with props.onClickFunction. Testing, all is good. 

 Something very powerful is happening here. The onClickFunction property allowed the button to invoke the App component’s incrementCounter function. It’s like when we click that button, the Button component reaches out to the App component and says hey parent, go ahead and invoke that incrementCounter behavior now. In reality, the App component is the one in control here, and the Button component is just following generic rules. 

 If you analyze the code as it is now, you’ll realize how the Button component has no clue what happens when it gets clicked. It just follows the rules defined by the parent and invokes a generic onClick function. The parent controls what goes into that generic behavior. That’s basically the concept of responsibility isolation. Each component here has certain responsibilities, and they get to focus on that. Look at the Display component too. 

 From its point of view, the message value is not a state. It’s just a value that the App component is passing to it. The Display component will always display that message. This is also a separation of responsibilities. As the designer of these components, you get to choose the level of responsibilities. For example, if we want to, we can make the responsibility of displaying the counter value part of the App component itself and not use a new Display component for that, but I like it this way. 

 This App component has the responsibility of managing the counter state. That’s an important design decision that we made, and it is one you’re going to have to make a lot in a React application, where to define the state. And the answer is usually simple, down in a tree as close as possible to the children who need to access that value on the state.

Components Reusability

One of the selling points about components is reusability, making a component generic enough so that we can reuse it in different cases. Let’s do that. Let’s make the Button component more generic. Let’s assume that we can pass in an increment value here, and the Button component will use that value instead of the hard coded one. So we’ll use the more generic Button component to create a +1 button, a +5 button, and so on. 

We need to upgrade this +1 here to something dynamic. It will be a property of the component, the amount to increment, and we’ll pass it down from the parent. Let’s name this new attributes increment, and the value we need to pass here is a number. Since the value here is not a string, we’ll need to use a set of curly braces here as well. So, for example, we can pass in 5. One quick note about this syntax here. 

We could pass the number like this, but the Button component in this case will see and work with that value as a string. So don’t do that. Keep it this way so the Button component receives it as a numeric value, not a string. To use this new increment prop, we can just access it here as props.increment. There we go. We’ve got a +5. So let me go ahead and add a few more buttons here and use increment values of 1, 5, 10, and 100. 

Let’s initialize this back to 0. And there we go. The UI rendered four buttons now with different labels, but they’re not going to work yet. In fact, all of them would still increment with a +1 at this point because we did not change their handlers. So the challenge now is to make each button increment the globally displayed counter by its increment value, not just 1. Do you think you can do that on your own? Give it a try. I saved the code as of now for you under 1.5 here. Here’s how I’d solve this challenge. 

This incrementCounter function here will now need to receive an increment value, and we can use its argument to do that. So receive incrementValue in here, and instead of using +1 we’ll use the new incrementValue. Now we can invoke the incrementCounter function with different values. The incrementCounter function is aliased as onClickFunction for the button. So the Button component needs to invoke the onClick function with an argument now, which is its own increment value, and that can be accessed using props.increment. 

But we can’t just pass the argument here like this, because remember, we need a function reference for the onClickEvent handler, and what I have on the screen right now is not a reference. It’s an invocation of a function. This will not work. But we can simply wrap this invocation in an inline function to make it into a reference, and through the magic of JavaScript closures, this will work just fine. But again, it’s a bit cleaner to do this logic inside the handleClick local function here. 

So let me go back to handleClick and put this new logic inside handleClick, just like that. Make sure this is still working, and all is good. This is the final code of this example, and I saved it here under 1.6 for you. Through this example, we’ve touched on the many basic React concepts, but this is still a relatively simple example. Let’s build something a bit more useful next. But first, I need you to absolutely understand the value you’re getting from using React’s tree reconciliation under the hood That’s the next video.

Tree Reconciliation in Action

You know the basics of React, and you’ve probably formed your initial impression about it. My initial impression was why go for all this trouble? Why use JavaScript to generate HTML? What exactly is the value I am getting from doing all that? Let me show you that value in action. 

In this example, which starts at 1.7 here, we have two simple DOM nodes, one being controlled with the native DOM web API directly using innerHTML and another being controlled with the React API, which in turn uses the DOM API. The only major difference between the ways we are building these two nodes in the browser is that in the HTML version, we used a string to represent the content, while in the React version, we used pure JavaScript calls and represented the content with an object instead of a string. 

There’s no JSX, and I will also use a regular JavaScript interval timer here to create some UI state so that we can do a stateful change for both versions. No matter how complicated the HTML user interface is going to get, when using React, every HTML element will be represented with a JavaScript object using a React.createElement call. Let’s now add some more features to this simple UI. Let’s add an input box that we can type into. To nest elements in our HTML template, it is straightforward in the HTML version. 

We can just add an input element like this, and it will render. We can do the same in React by adding more arguments after the third argument for React.createElement. To match what we did in the native HTML node, we can add a fourth argument here that is another React.createElement call that renders an input element. This input element has no attributes and no children. There we go. Okay, not too bad so far. Let’s add another node to both trees. 

This time, let’s render the current time. I have a JavaScript line here that you can use to display the current time. Just include this in both versions. Since the first version is a template string here, if you notice these are backticks and not single quotes, so this makes the innerHTML a template string, and I can use a dollar sign syntax here and include the JavaScript line to render the time. Let me put this value inside a pre tag just to give it some monospaced font. Test that. The time is showing up. 

To add the timestamp in the React version, we add a fifth element to the top‑level div element. This new fifth element is another React.createElement call. This time it’s a pre tag as we used in the HTML version, no attributes as well, and the new date String for content. Both the HTML and React versions are still rendering the exact same HTML in the browser. But as you can see, the React way is a lot more complicated than the native DOM way. 

So let me ask you the question again. Why go for all this trouble? What is it that React does so well that is worth giving up the familiar HTML and having to learn a new API to write what can be simply written in HTML? The answer is not about rendering the first HTML view. It’s about what we need to do to update any existing views in the DOM. So let’s do an update operation on the DOM that we have so far. Let’s simply make the timestamp tick every second. 

We can easily repeat a JavaScript call in the browser using the set interval web timer API. So let’s put all of our DOM manipulations for both the HTML and the React versions into a function. I’m going to name this function render. This can be a simple arrow function just like that. And I’ll copy all of this code and put it inside the render function. We can then use this setInterval call to invoke the render function every second. So this should work now. 

When we refresh the display area, the timestamp string should be ticking every second in both versions. We are now updating our user interface in the DOM, and this is the moment when React will potentially blow your mind. If you try to type something in the text box of the HTML version, you will not be able to. This is very much expected because we are basically throwing away the whole DOM node on every tick and regenerating it. However, if you try to type something in the text box that is rendered with React, you can certainly do that. 

Although the whole React rendering code is within our ticking timer, React is changing only the timestamp text and not the whole DOM node. This is why the text input was not regenerated and we were able to type in it. You can see the different ways we are updating the DOM visually if you inspect the two DOM nodes in the Chrome DevTools elements panel. The Chrome DevTools highlight any DOM elements that get updated. You will see how we are regenerating the entire first mountNode element with every tick, while React is smartly only regenerating the content of the pre element in the second mountNode. 

This is React’s smart diffing algorithm in action. It only regenerates in its DOM node what actually needs to be regenerated, while it keeps everything else the same. This diffing process is possible because of React’s virtual DOM and the fact that we have a representation of our user interface in memory because we wrote it in JavaScript. For every tick in this example, React keeps the last UI version in memory, and when it has a new one to take to the browser, that new UI version will also be in memory. So React can compute the difference between the new and the old versions. 

In this example, the difference was the content of the pre element. React will then instruct the browser to update only the computed diff and not the whole DOM node. No matter how many times we regenerate our interface, React will take to the browser only the new partial updates. Note that the HTML version can be easily changed with a few more lines to make it update only the content of the pre element as well instead of the whole thing. 

But that requires some imperative programming. We’ll first have to find the element that needs changing in the DOM tree and add some more imperative logic to change its content. We are not doing that in React. We’re being declarative in React. We just told React that we’d like a pre element with the date string. No imperative logic is here, and yet we’re still getting the efficiency of a tuned‑up imperative alternative. This is the subtle power here. 

The React way is not only a lot more efficient, but it also removes a big layer of complexity about the way we think about updating user interfaces. Having React do all the computations about whether we should or should not update the DOM enables us to focus on thinking about our data and state and the way to model that state. We then only manage the updates that’s needed on the state without worrying about the steps needed to reflect these updates in the actual user interface in the browser because we know React will do exactly that for us, and it will do it in an efficient way.

Wrap Up

A React application is a set of reusable components. Components are just like functions. They take input and they output a description of a user interface in the form of a React element. The ReactDOM library enables us to render those React elements in the browser, and it will rerender them for us automatically when their in‑memory state changes. To accomplish this, we write the component’s markup using the React JavaScript API. 

Writing HTML in JavaScript is a lot different than what we’re used to. But luckily, React has a way to write the virtual DOM in a syntax very close to the HTML syntax we’re used to. This special React syntax is called JSX. Once we have the virtual DOM description in JSX, we can pre‑transform it to valid React API calls before shipping it to the browser. 

Browsers do not have to deal with JSX. The input for a component is a set of properties you can access inside the component with its first argument object, which is usually named props, and also a set of state elements that a component can hook into with the special useState function. A component state can be changed inside that component, and every time a component changes its state, React rerenders it. 

The props of a component cannot be changed by the component, but the whole component can be rerendered with different props by the component’s parent. The syntax to mount a React component in the browser is ReactDOM.render, and that takes two arguments, the component to render and the HTML element to hold the React‑rendered markup. React also comes with normalized events that work across all browsers in a standard way. 

We’ve seen the onClickEvent handler in this course module, and there are other onSomething events like onChange and onSubmit, and many others. React actually has two types of components, function and class components. We’ve only seen function components, but I’ll be covering class components in future videos as well. However, before we start another application on React, let’s get you comfortable with all the modern JavaScript syntax that’s usually used in the React ecosystem. That’s our next course module.

Exit mobile version