28 Apr 2015
In the MVC (Model-View-Controller) pattern, React can be thought as the View. It uses the concept of virtual DOM to avoid unnecessary DOM manipulation (which is expensive) and it uses one-way reactive data flow that can the logic of the application *  .
In this post we’ll cover the basics concepts and features of React through a set of small examples.
React can be easily included with external libraries and is also available as npm packages, but for the sake of simplicity and ease of experimenting with the examples, we’ll be using JSFiddle in this tutorial.
JSFiddle requires some setup to work, especially due to JSX syntax. The easiest way to try the examples yourself is forking the examples we’ll provide here.
Let’s start with the simplest example: a simple stand alone component that renders the following markup:
There are a couple of observations we can make here. First off, the JSX syntax. Note how we pass an XML tag to the
React.render() function. It’s a syntax sugar JSX provides, and it gets transpiled to a function call, in particular:
where HelloWorld is the react class we created above. The same is true for the
<div> tag in the
render() method. In this case though, it’s a base HTML element, so it has a builtin function in React:
Finally, all React classes must implement the
render() method, which returns other React components, which will eventually get converted to DOM elements and set as children to
document.body. If we inspect the HTML source of the generated page we can see the generated tags:
Terminology. We refer to the object passed to
A static component is not very flexible, so to be able to customize the component, we can pass parameters. Let’s suppose that instead of rendering Hello World, we want our component to render Hello plus some custom message. We can use props (short for properties) for this (jsfiddle):
In this version, we are passing a property, text, to the Hello instance, and it’s read within the class using
this.props.text. More generally, this.props is an object that contains all properties passed to it.
Even though it’s optional, I think it’s a good practice to list the accepted properties a component can take by setting the propTypes property in the react class definition. It expects an object where the keys are the possible properties and the values their types. The possible types are in
In our case, we expect text to be a string, so we can simply do (jsfiddle):
Besides documenting the component, it will add type-checking for free. In this case, passing something other than a string will raise a warning.
We can think of props as arguments to the constructor of a class. Classes are usually stateful, that is, they make use of internal variables to encapsulate logic, to isolate implementation details from the external world.
The same idea can be applied to React components. The internal data can be stored in an object called
Let’s create a simple element to display the number of elapsed of seconds since the page was loaded (jsfiddle).
There are a couple of new concepts to be understood in this example. First, we implemented the
getInitialState(), which initializes the object this.state when the component is instantiated. In this case we are initializing one state called count. The
render() method reads from that variable.
We also implement the
componentDidMount() method. We’ll explain what it does in more detail later, but for now, it’s important to know it’s called only once and after the
render() method. Here we are using the
setInterval() function to execute the
updateCount() method every second. In general, if we are passing a callback that is a “method” (function from an object), we usually want to provide the context, which is normally this, so we would need to call
update() function will read from
this.state and increase it. By calling
this.setState(), not only it will set
this.state.count with the new value, but will also call
render() again. As we mentioned before, the second call of
render() doesn’t cause the
componentDidMount() to be called.
This pattern of calling
render() constantly is pretty common in dynamic GUIs and in React it was modelled in a way that
render() is a function of
this.state and we don’t have to worry about keeping track of when to re-render the screen after changing data.
React components can return other custom components in their
render() method and also we can nest React components. One simple example is the following (jsfiddle):
Container returns two other React components,
Item is nested within
List. The list of components nested within another component is available as
this.props.children, as we can see in the
Updating. We saw that whenever we change states (by calling
setState()), it triggers a re-render. When a component is instantiated from the
render() method of another component, calling
render() will also trigger updates to it (and recursively, the nested components). To illustrate that, let’s modify the example above with the following (jsfiddle):
There are a couple of new things here. First, we added the native button component and passed a callback to the onClick property. It’s the equivalent to the
onclick for DOM elements. Whenever the button is clicked, we toggle the state representing the type of list to render (ordered/unordered).
Container.render() method is invoked, the
render() method from
Item is called as well. For the list it makes sense, because its render function depends on
props.ordered that is being changed. None of the
Items are changing thought, but it gets re-render nevertheless. That’s the default behavior from React. In the “Cached rendering” section, we’ll see how to customize this.
Again, note that a component is only updated if it’s instantiated starting from a
render() method. For example, both
Item are created when
Container.render() is invoked. On the other hand, even though
Item is used within
this.props.children) it’s not instantiated there, so it doesn’t get updated if
List.render() is called (jsfiddle).
DOM manipulation is usually the most expensive operation in highly dynamic pages. React addresses this bottleneck by working with the concept of virtual DOM. After the first
render() gets called, React will convert the virtual DOM to an actual DOM structure after which the component is considered mounted (and
componentDidMount() is called).
Subsequent calls of
render() changes the virtual DOM, but React uses heuristics to find one what changed between two virtual DOMs and only update the difference. In general only a few parts of the DOM structure is changed, so in this sense React optimizes the rendering process and let us simplify the code logic by re-rendering everything all the time.
This process of updating only part of the DOM structure is called reconciliation. You can read more about it in the docs *  .
We need to be careful with conditional rendering, since it can defeat the purpose of the virtual DOM. We used conditional rendering in the React Children section, in the
List.render() function. Let’s create a similar example, to make the problem clearer (jsfiddle):
Here we introduced two dummy new React classes,
Text2, which render “Hello” and “World” respectively. The
render() function of
Container returns one of the other alternated.
If we run this example, we can verify
Text2 get mounted every time
Container.render() is called. The reason is that whenever React runs the diff heuristic, the previous tree is completely different from the other.
One solution is to always render both components, but hide one of them using CSS. A proposed solution for the example above is here.
As we saw in the React Children section, we may trigger
render() of a component even when nothing has changed at all. In 99% of the cases, it’s probably fine, because React will be smart enough to prevent DOM manipulations, which is the expensive part anyway.
In case the
render() call is expensive, we can control when it gets called by implementing the
shouldComponentUpdate() method. By default, it always returns true, but it receives the next set of props and state, which we can inspect to determine whether anything has changed.
Comparing complex objects can be tricky if we don’t know the structures very well. Also caching in general introduces complexity. For example, whenever we do any changes to our code, we need to make sure to update the
shouldComponentUpdate() logic, otherwise the
render() function might not be called when it should.
Another issue is that props and state can be mutated without the parent component changing them or without calls to
setState(). This can cause unexpected problems. Consider the following example (jsfiddle):
Here we only have one state, data, an object with a single key. This is a simple enough object to cache, right? But in the example, if you click “Update”, even though we did mutate the state and called
setState(), it doesn’t do anything. The reason is that in
this.state.data are references to the same object.
Inserting an existing DOM subtree under a React component requires more work. As we saw, React works with the concept of virtual DOM, but we have access to the actual DOM after the component mounted. In particular, we can do it at the
componentDidMount() method. In the example below, we create a toy text DOM node, and insert into the generated div DOM element (jsfiddle).
Here we are artificially creating a fake text node, but we could potentially insert an entire subtree under the div element. React enables referring to components by ids. In this case, we just need to add the ref property with an unique identifier. Later, when the component is mounted, the corresponding DOM element reference will be available at the
this.refs object. More in refs *  .
Some frameworks are created to implement patterns. There’s a natural tradeoff between how much boilerplate it saves someone vs. how much it limits it. React is relatively low-level, and thus it still offers a lot of flexibility. One constraint that is imposes it’s the one-way communication between components, that is, during render, we can only pass information from the parent to the children. It’s possible to pass information from children to parents via callbacks, but that usually triggers re-renders.
I struggled in this paradigm right in the beginning, but in the long run, this constraint makes the code much simpler, especially when we have many components interacting with each other, and tracking down what is affecting what is a pain. With the one-way communication, we tend to concentrate logic in fewer places, and if we think in terms of graph theory, each component bring a node, React forces us to have a tree, whereas in an unconstrained environment, we can have arbitrary graph structures.
To make it clearer, let’s try a very simple example. We want a component with a selector and a list, but depending which value of the selector, the list displays a different set of items (jsfiddle).
Note how we store the selected value not in
Selector, but rather in the parent of
Selector cannot communicate with List directly. Now,
Container is the source of truth and both
List only read from this value.
React can be thought as a state machine with many stages. It offers hooks to some these stages, some of which we didn’t cover here, but it’s good to have a picture.
The following chart represents the sequence of function calls (click for a full image). The blue nodes at the top represent external actions and the yellow nodes represent the methods that get called in sequence when that happens:
In this post we covered a couple of features from React by small examples.
React.js is a pretty neat framework and is very fun to work with. I’m trying to study more advanced use cases, especially regarding exception handling and performance, so if I find anything interesting, I can write new posts.