left-icon

React.js Succinctly®
by Samer Buna

Previous
Chapter

of
A
A
A

CHAPTER 2

Why React?

Why React?


HTML is a great language, and what makes it great, in my opinion, is how it allows us to be declarative when building our web pages. We basically tell the browsers what we want with HTML.

For example, when we tell the browser to render a paragraph of text in a page, we don't care how the browser is actually going to do that. We don't have to worry about what steps the browser needs to do to make our text look like a paragraph, such as how many pixels of white space should be around it, how many words to display per line, or what to do when the screen is resized. We just want a paragraph, and with HTML we have the power to command the browser to make it happen.

But HTML by itself is not enough. We don't have loops, if statements, or variables in HTML, which means that we can't write dynamic HTML based on data. HTML works great for static content, but when we have data in the equation, we need something else.

The simple truth is: data is always in the equation. We write HTML to represent some data, even when we use HTML for static content. When we write static content, we are manually writing HTML by hand to represent some data, and that's okay for small sites where the data is not frequently changed.

The word “change” is key here. When the data we represent with HTML gets is changed, we need to manually update the HTML to reflect that change. For example, when that small business for which you built a website gets a new phone number, it’ll be time to drop into an HTML editor, domake that change, and then upload the new HTML files to the server.

If the nature of the change is more frequent though, for example, if the business now wants to feature a different product on the home page every hour, you will not agree (I hope) to domake that manual change every hour. Imagine if Facebook was all static content, and every time you update your status someone at Facebook needs to edit an HTML file and upload it to the server.

We realized (dozen of years ago) that HTML is not enough, and we have since been trying to enhance HTML to make it support dynamic content.

Let’s assume that we want to represent a list of products in HTML. For every product, we have a name and a price. Here’s some sample data:

Code Listing 1: Sample Products Data

{

  "products": [

    { "name": "React.js Essentials", "price": 2999 },

    { "name": "Pro React", "price": 2856 },

    { "name": "Learning React Native", "price": 2199 }

  ]

}

A small business mentality would reason that we have only these three products, and their prices rarely change. Manually writing some static HTML for these three products would be okay.

But a list of products is dynamic—some products will be added, some will be removed, and the prices will change seasonally. Manually writing HTML will not scale, so we need to come up with HTML that always represents the last state of the products’ data.

Generating HTML

We can use database tables (or collections) to represent data in a database. For our products example, we can use a products table.:

Code Listing 2: Products Table

create table products (

  name text,

  price integer

)

The Rrows of this table each represent a single product. We can then give the client write access on the table to allow them to add, remove, and update their list of products whenever they want.

To come up with HTML to represent these products, we can read the last state of the data from this table and process it in some programming language—like Java—to make the program concatenate together HTML strings based on the data.

Code Listing 3: HTML Strings

html = "<html><body><ul>";

// Loop over rows in table, and for every row:

html += "<li>" + name + " - " + price + "</li>";

// When the loop is done:

html += "</ul></body></html>";

We can now write the value of that html variable to an HTML file and ship it. Every time the customer updates their data table, we can regenerate and ship the new HTML.

This worked great, and it gave us a lot of power to work with dynamic data, but something was wrong; it didn't feel right.

We wanted to write HTML, not concatenate strings.

Enhancing HTML

A genius mind came up with an idea to create a new language that is somewhere between HTML and programming languages like Java. A language where we can still write normal HTML tags, but also use special tags that will act like loops and conditionals when we need them. JSP and PHP are examples of this.

Here's how we can represent our product data using an enhanced HTML language:

Code Listing 4: HTML+ (Pseudocode)

<html><body><ul>

  <% FOR each product in the list of products %>

    <li><%= the product's name %> - <%= the product's price %></li>

  <% END FOR %>

</ul></body></html>

This is clearly a bit more pleasant to work with than concatenating strings. The compiler will take care of doing the string concatenations for us, and we will get HTML that always reflects our exact data.

This has been the standard way to create dynamic websites for years. In fact, until recently, Facebook did exactly that to show you the list of updates from your friends.

But just like everything else in life, browsers evolved and became smarter. JavaScript became a standard language that is supported in all browsers, and someone invented AJAX, which allowed us to ask servers questions in the background of a web page.

We realized that we could be more efficient in the way we represent our data. Instead of preparing the HTML server-side and shipping it ready to the client, we can send just the data to the client, and we'll have the fancy, smart browsers prepare the HTML themselves. JavaScript can do that.

Since we didn't want to concatenate strings, we needed something like JSP and PHP, but something that would work with the JavaScript engine in the browser.

Frameworks like Angular, Ember, and a handful of others were developed to make this process easier.

Just like server-side enhanced HTML languages, with Angular we do:

Code Listing 5: Angular Loop

<html><body><ul>

  <li *ngFor="#product of products">

    {{product.name}} - {{product.price}}

  </li>

</ul></body></html>

Now we're being more efficient over the wire, and we are generating dynamic HTML without having to deal with concatenating strings.

This worked great, but as we used it to build big applications, a few issues came up:

  • Performance: sSince we are no longer hitting the refresh button every time we click a link, our use of memory should now be managed more carefully.
  • Browsers are great for rendering an HTML tree of elements dynamically, but they are still slow, especially when we need to update the tree. Every time an update is needed, there are tree traversals that need to happen, and when we reach the node and update it, the browser needs to redraw the user screen, which is an expensive process.
  • In some cases, we were not modeling the state of our data directly with user interfaces, and instead, we were writing code that expressed the steps and the transitions needed to update those interfaces. This is not ideal.

React’s way

The engineers at Facebook, realizing the problems of all other JavaScript frameworks, wanted something better, so they went back to the drawing board. A few months later, they came up with what eventually became React.

They had a couple of simple rules to guide their genius solution:

  • Enhancements to HTML are noise—let's just concatenate strings in JavaScript itself, and yes, sacrifice some readability for performance.
  • The DOM is a bottleneck; we should avoid it as much as possible.

HTML views are hierarchical. It's a big tree of nodes, and we have nodes within other nodes. With this concept clearly realized, maybe instead of concatenating strings, we should be working with nodes.

Having the power and flexibility of JavaScript, Facebook engineers realized that, if HTML nodes were represented as JavaScript objects, we would have a new world of possibilities to work with them.

That led to their first major decision: Represent every HTML element with a JavaScript object.

Note: If you want to test the React code samples in this book, the easiest way to get a React environment for testing is to use one of the web development online playground online applications. My favorite is JS Bin; here's a React-ready bin that you can fork to start testing.

React’s API today has the createElement function, which can be used to do exactly that.:

Code Listing 6: Void Element

// Instead of:

<img src="logo.png" />

// We do:

React.createElement("img", { src: "logo.png" })

The createElement function returns a JavaScript object. To inspect that object, go to the main React website and paste the createElement line in the developer tools JavaScript console:

createElement in JS console

Figure 1: createElement in JS console

Notice the type property for that object, and take a look at the props property as well.

<img />, however, is a void (self-closing) element; let's take a look at another example for a normal element.:

Code Listing 7: Normal Element

// Instead of:

<a href="/">Home</a>

// We do:

React.createElement("a", { href: "/" }, "Home");

To represent a parent-child relation, we can use the arguments of the React.createElement function. We can pass one or more React objects, starting from the third argument of React.createElement.

For example, to make the logo image clickable:

Code Listing 8: Parent-child Relation

// Instead of:

<a href="/">

  <img src="logo.png" />

</a>

// We do:

React.createElement("a", { href: "/" },

  React.createElement("img", { src: "logo.png" })

);

If we inspect this last object in the console, we’ll notice how the props attribute for the <a> element has a children attribute, and that in turn holds the object for the <img /> element. This is how we represent a tree with React.

Of course, under the hood, React will eventually generate HTML strings from these JavaScript objects and concatenate them together.

There are big benefits to writing HTML with JavaScript:

  • We have the power of JavaScript itself to work with data. Our product example becomes:

Code Listing 9: The Power of JavaScript

React.createElement("ul", {},

  ...products.map(product =>

    React.createElement("li", {}, `${product.name} - ${product.price}`)

  )

);

  • It's all JavaScript, so we don't mix HTML with new tags or anything. We also don't have to learn a new language, and instead learn how to use the few JavaScript functions that React defines.
  • We'll always have a representation of our HTML in memory, separate from the one in the browser. This means that we can optimize our DOM operations by using a smart diffing algorithm on the structures we have in memory. This is only relevant when things change. This concept is what we call Tthe Vvirtual DOM in React.

The Virtual DOM

After rendering HTML for the products data example that we started with, we’ll have three products with their names and prices displayed in the browser. With an Ajax call, we've determined that the price for product #2 has changed, and we now have a fourth product to display.

React has the original Uuser Iinterface state for three products stored in memory (because we wrote it in JavaScript first). Before sending anything to the browser, React will compute the new state, which now has four products.

With both states available in memory now, React can compute the difference between the new state and the original state, and it can conclude that it needs to add a node #4 and modify node #2. All other nodes will remain unchanged.

Having the original state remembered in memory represents a big performance benefit. Other frameworks that don’t have an original state in memory have two options:

  • Generate the new state’s UI and replace the whole tree in the browser.
  • Try to change nodes #2 and #4, but rely on what is in the DOM. This results in making a bunch of READ operations in the DOM, and processing the tree to figure out where node #2 begins, and where node #3 ends. These DOM operations are usually expensive.

React’s virtual representation of the browser's DOM in memory (known as the vVirtual DOM) is clearly a better alternative. In fact, it's so good that most other JavaScript frameworks today have changed their algorithms to do exactly what React does for updating the DOM.

React’s power is more than a Vvirtual DOM with a smart diffing algorithm. Views in React have private state, so our product list view can have its original three products object represented in that private state, and when the new data comes in, we just update the private state. React triggers a DOM reload whenever the private state of the view changes. It basically hits a special refresh button in the browser.

From the point of view of a user inspecting the state, the view has been completely refreshed, and the new view represents the new state. But under the hood, React is doing this refresh operation smartly by using the diff it computed via the virtual DOM, and only applying that diff to the browser's tree. As developers, however, we don't have to worry about that; we just declare our state changes and let React take care of the steps needed to get those changes efficiently reflected in the browser's DOM.

This is so important to understand that it's worth repeating: wWith React, we model the state of our user interfaces, and not the transitions on them. If there are changes, we just model the new state.

React has effectively taught both the browsers and us developers to speak a new language: the language of user interface outcomes. We can now communicate with our browsers in this higher-level language that allows us to express our user interfaces in a declarative way.

Using the React language for our products example, we're basically saying, “Browser, I have three products for you.” Then a minute later, we'll come back and say, “Browser, I now have four products for you.” We don't have to worry about the changes in the prices or names, since this is not part of the language; it's a transition, and we just model the new state: four products. In fact, even the number of products does not matter because of the reactive update nature of React, which will take care of re-rendering the views when that number changes. Our command to the browser ends up being, “Browser, we have a list of products for you, and changes might happen to that list.”

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.