How You May Have Come Up With React

Inter Caetera
6 min readApr 3, 2019

--

The fact that React has entered the JavaScript world for good is nothing to be disputed. Because of this, newcomers to JavaScript often don’t question the need for front-end frameworks and libraries like React and immediately assume it’s a requirement for any browser application.

While it is true React is immensely useful, you may not immediately realise why that is. So, let’s go on a little journey through a hypothetical application to understand how you may have come up with the fundamentals upon which React is built.

Byzantine scholars are always good actors instead of boring Lorem Ipsum.

Let’s imagine that we have an interface written in HTML and CSS that currently only has static content. We created a few simple cards and now would like to populate them with dynamic data. In the olden days, we would do it by processing our markup on a server with PHP, echoing as much HTML as necessary and that would basically be it.

However, with the advent of AJAX, single page applications became more widespread. We now can fetch data using the fetch API. This requires rebuilding our interface in the browser rather than on the server. No longer do we have the luxury of sending the entire page every time there is new data — it comes to us asynchronously and it is up to the browser to render it.

Let’s imagine that we prototyped the following markup as content of one of the cards.

If we were still in 2003, we could simply substitute variable data for PHP variables, wrap this into <?php> tags and call it a day. However, in this scenario, we are in 2019, but adamantly opposed to using front-end frameworks.

I will ignore the AJAX part of this task for reasons of space, and also because it’s not very relevant to the topic at hand. We’ll keep our data inside a JSON const in our script file.

const data = [
{
name: 'Anna Komnene',
avatar: 'https://i.imgur.com/dE1Xhg4.png',
description: '"The truth is all barbarians are usually fickle and by nature unable to keep their pledges."',
},
{
name: 'John the Grammarian',
// ...

Let’s begin with a very naïve approach, converting the hypothetical PHP example to JavaScript. We could do something very stupid like this:

This is fairly straight-forward. We can utilize template literals to render strings directly to HTML. It’s fairly easy to implement and understandable at a glance.

However, any seasoned JavaScript developer will cringe at this implementation. We do not sanitize user input and do not do anything besides echoing out what is in the strings. If our data contained any user-generated content, we’d be wide open for a cross-site scripting (XSS) attack. Sanitizing this data would not be particularly difficult, but if you were to attempt it on a larger scale you would realise quickly that it does not scale well.

On top of that, innerHTML essentially recreates the DOM tree from scratch every time. This means that if we had any existing event listeners attached to these nodes, they would be overwritten. We can do better.

This is a much cleaner approach, although it still requires quite a lot of repetition. Using textContent ensures that any stray XSS code that would find its way into our data does not get executed. Also, building the DOM manually is much more efficient and clean than doing it with innerHTML.

However, you’ll notice that there is a lot of repetition in this as well. For each of these elements we repeat the same code: each uses createElement and each uses appendChild. We can create a function to simplify this.

This helped slightly: we created a function called createElement which takes an element type (basically the HTML tag), the reference to the element’s desired parent and a function which allows us to operate on this element further.

Theoretically, because we are using a function to operate on the newly created element, we could also do something like this:

However, you’ll notice that we only really do two things here: assign attributes and modify the text content. So we could generalize this even further.

Our code is starting to get more complex. Our createElement function has gained two new pieces: first we iterate over the attributes object passed into it and add them to our DOM element. Then, if there is content to add, we add it.

However with this approach, you’ll notice that we lost the interesting property of chaining createElement functions together. That would be a desirable feature — because since the function is now more robust, we could, ideally, create an approximation of the DOM tree by nesting these functions.

Let’s modify the createElement function to support this.

This modified the interface of the createElement function, however it is now much simpler to call, even if it grew in size slightly. Let’s examine more closely what this function actually does.

First, we create a DOM node using the createElement method. That’s simple.

Then, we check if we have any attributes to process. If we do, we iterate over the keys of those attributes and set them to our newly created element.

Then, we check if there is an array of children passed. If there is, we iterate over it. Children can have two types, they can either be strings or objects. If they are strings, we create a text node and append it to the element (we cannot just assign textContent here because there may be other children and such assignment would overwrite them).

If a child is an object, we just call createElement recursively, applying the properties of that child to the function, with the exception of parent, since it’s obviously a child of the currently processed element.

This changes our implementation to this:

And this is approximately what a React functional component is. Behind fancy JSX syntax, behind its clever naming, behind really nice implementation of a virtual DOM and behind many, many optimisations, that’s all there is to it. At least conceptually.

In its simplest terms, it’s all just a function that takes props as an argument and returns a component.

Almost like innerHTML, wouldn’t you agree?

📝 Read this story later in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--