Front-end and JavaScript in particular are a strange world. The amount of new things being rolled out on a daily basis is often ridiculed by people that don’t work with them, and many that do. Still, at times, we get a bit overwhelmed with new information, libraries, and discussions, and we would like something stable, like a safe haven for ships where we can stay for a bit longer. As of late, React seems to be this docile harbor in a sea of dynamic JavaScript evolution.

With that in mind, we decided to produce this multi-part React tutorial, to showcase its capabilities and see how it compares to Angular and VueJS.

Illustration of React as a lighthouse clearly displayed over a sea of JavaScript code

Of course, React is not the only harbor that we can use, but at the moment, it is one of the most popular, stable, and innovative solutions, and while it still gets plenty of upgrades, they are more an option for improvement than than a necessity for function.

The State of React in 2019

React is a view library that we can track back to as early as 2011, when its first prototype, called FaxJs, appeared on its Facebook page, React itself was introduced by Jordan Walke (who is also an author of mentioned prototype) at JSConfUS on May 29, 2013, and was made openly available on GitHub on July 2, 2013.

React continued to gain popularity in 2014, when conferences started to appear to expand the community and popularize React. From my perspective, though, 2015 was a milestone year for React—big companies (e.g., Airbnb and Netflix) started to like and adopt React. Also, React Native appeared that year. The idea behind React Native wasn’t something absolutely new, but it was interesting to watch, especially as it was backed by Facebook.

Another big change was Redux, a Flux implementation. This made state-management way more approachable and easier, making this the most successful implementation to date.

Between then and now, plenty of other things became available, including React tools, a core algorithm rewrite, Fiber, a change to semantic versioning, and so on. Fast forward to today, we are on 16.6.3, probably a few weeks before the new version with Hooks becomes available (it was supposed to be 16.7.0, but that one is already released due to some fixes for React.lazy). React is well known and stable and getting great opinions.

But What Is React?

Well, if you are front-end developer and you haven’t heard about it yet, then I need to say congratulations are in order, as that’s quite a feat.

Jokes aside, React is a declarative component-based view library that helps you to build UI. It is a library, not a framework, though at first, many people described it as the latter.

Obviously, if we are going to add Redux, React Router, and so on, it starts to have all necessary things to make a regular single-page application, which might be a reason why it is sometimes mischaracterized as a framework rather than a library. If anything, it could be argued that, with all the components of that environment together, the term “framework” is somewhat fitting, but on its own, React is just a library.

Let’s stop with the nomenclature and focus on what is different in React, on the things we did not have prior to its inception. First of all, when you first think about React, you think JSX, as it is the first thing that comes in your sight when you look at the code. JSX is a JavaScript syntax extension that somewhat resembles HTML/XML. When it comes to React and JSX, we have a few differences from HTML, e.g., a class in React is className, there is no tabindex but tabIndex, the style accepts JavaScript objects that have camelCased properties, and so on.

There are some minor differences, but anyone should pick them up in no time. Event handling is through, e.g., onChange and onClick attributes that can be used to attach some function to handle events. Also, components later can be freely reused and customized by using props, so there is no reason to write the very same code few times.

import React, { Component } from 'react';

export default class App extends Component {
    render() {
        return (
            <div>Hello World, {this.props.name}</div>
        );
    }
}

However, JSX is actually not absolutely necessary in React. You can write regular functions to create elements without using JSX. The same code that is above, can be used like below.

import React, { Component } from 'react';

export default class App extends Component {
    render() {
        return React.createElement(
            'div',
            null,
            'Hello World, ',
            this.props.name
        );
    }
}

Obviously, I am not suggesting you use such syntax, though there are cases where it might come handy (e.g., you want to introduce a really small thing and don’t want to change the build environment).

Actually, I have another reason why I showed the snippet above. Often, developers do not understand why we need to do the following:

import React from 'react';

The snippet should be self explanatory. Even though we are extracting Component, we still need React, because Babel transpiles above JSX to below React.createElement. So, if we don’t import React, it will simply fail for us. I mentioned Babel, which is a tool that help us introduce things that are not in JavaScript yet (or rather in browsers) or are somehow extensions to it (or different languages like TypeScript, which Babel supports from Babel 7). Thanks to Babel:

  • JSX will be made into functions that are understood by the browser.
  • We can use new features that aren’t yet in browsers (e.g., class properties).
  • We can add features that are in newer browsers but aren’t there in older ones while maintaining older browser support.

In short, tomorrow is today in JavaScript; this is probably something that would require its own article. It is worth mentioning that the React import can also be bypassed by some other techniques (like introducing ProvidePlugin through Webpack and so on), but due to limited space here, we will avoid it and assume that the user will user use Create React App (CRA) (more about this tool will be mentioned later).

The second important thing, and far more important than JSX itself, is that React is based on the virtual DOM. In short, the virtual DOM is memory of an ideal tree which is represented by JavaScript that the developer writes, which is compared later with real DOM and synced with it in a process called reconciliation.

How Does React Compare to Angular and Vue?

I quite dislike comparing libraries, especially when we are forced to compare pears to apples (libraries vs. frameworks and so on).

Therefore, I will try to compare React to Angular and Vue using a series of short questions and answers that don’t have much to do with technical stuff rather than saying something like “X is better than Y because it uses JSX and not templates.” Points such as these are usually personal preferences, one’s subjective choices. Also speed, memory allocation, etc., are quite similar in React and all its major competitors (Angular and Vue comes to mind). There is a really good report on the matter, but please keep this in mind: The vast majority of applications do not look like really big tables that swap rows in a 10k table. Therefore, these results also are a pure speed experiment. In the real world, you would not do such a thing in the first place.

Illustration of React vs. Angular vs. Vue.js

So let’s take a look at some questions pertaining to React and how it compares to the competition:

I want to have plenty of job opportunities. How popular is React?

Well, that’s an easy one to answer—pick React. Actually, I would say that React has roughly 6-10 times (quite a big spread, but there are some portals where it is 1:50 and some where it is 1:6) more job openings than Vue and 2-4 times more than Angular. Demand for React experts is strong, so why is Vue so popular on GitHub (it has more stars than React in fact) yet has fewer job openings? I have no idea.

I want a big community, plenty of libraries, quick solutions for problems that might arise.

React. Look no further.

Is it easy to use and does it make development enjoyable?

Once again, according to the State of JS reports for 2018 and 2017, both React and Vue enjoy a really good reputation and most developers say they would use them again. Angular, on other hand, has a tendency, year over year, to send more and more people saying that they would not use it again.

I want to create a new single-page application, but I do not want to search for libraries.

That’s probably the only place where I would say Angular is the better choice.

No big corporations. I want to be as independent as possible, which should I choose?

Vue—it is the only independent one in our big trio. (Facebook is backing React, while Google is behind Angular.)

Easiest start and fastest learning curve?

Vue/React. I am leaning toward Vue here, but that is just my personal opinion.

Why? Because you do not need to even know JSX (it is optional) and it is basically just HTML + CSS + JavaScript.

React Tutorial: Getting Started on Your First App

React tutorial: Screenshot of the success message for creating a React app

The easiest way to start with React nowadays is to use CRA, a CLI tool that creates a project for you and helps you avoid all the necessary settings for Webpack/Babel and more. Instead, you rely on how it is configured by default and what’s been included in it over time. Thanks to that, you do not need to care about major updates for some critical libraries.

Of course, later on, you can “eject” yourself and handle every single aspect on your own by running npm run eject. This approach has its own strong points, as you can enhance your app with things that would otherwise be unavailable (e.g., decorators), but it can also be a source of headaches since it requires many extra files and a lot more time.

So, the very first thing to do is:

npx create-react-app {app-name}

Then npm run start and you are ready to go.

Class vs. Function Components

We should start by explaining how these components differ. Basically, each component can be a function or class. The main difference between them is that the class one has some features that are unavailable in function component: they can have a state and use refs, lifecycle, etc. That’s the current state of play, and as of version 16.7 (or however it will be called due to already mentioned changes), we will have hooks as well, so state and refs will be possible with hooks.

There are two types of class components: Component and PureComponent. The only difference between the two is that PureComponent is doing shallow comparison of props and state—it has its own benefits in a situation where you do not want to make “wasted” renders, where a component and its children are in exactly the same state after a render. Still, it is only a shallow comparison; if you want to implement your own comparison (e.g., because you are passing complex props), just use Component and override shouldComponentUpdate (which by default returns true). Since 16.6+, something similar is also available with function components—thanks to React.memo which is a higher order component and by default behaves like PureComponent (shallow comparison), yet it takes a second argument where you can pass your own custom props comparison.

As a general rule of thumb, if you can use the function component (you do not need class features) then use it. Soon, starting from 16.7.0, using class components will only be required due to lifecycle methods. I tend to believe that function components are more transparent, easier to reason about, and to understand.

React Lifecycle Methods

Illustration of mounting, updating, and unmounting components

Constructor(props)

  • Optional, especially with CRA being that popular, where class field declarations for JavaScript are included as default. It is pointless to declare if you are binding your methods by arrow function within the class body. A similar state can be also initialized as a class property.
  • Should be used only for initializing local state for object and binding methods in ES6 classes.

componentDidMount()

  • Make Ajax calls here.
  • If you need event listeners, subscriptions, and such, add them here.
  • You can use setState here (but it will make the component rerender).

componentWillUnmount()

  • Cleans all stuff that is still ongoing—e.g., Ajax should be interrupted, subscription unsubscribed, timers cleared, and so on.
  • Do not call setState, as it is pointless because the component will be unmounted (and you will get a warning).

componentDidUpdate(prevProps, prevState, snapshot)

  • Happens when the component just finished updating (doesn’t happen on initial render).
  • Has three parameters that are optional to use (previous props, previous state, and a snapshot that will only appear if your component implements getSnapshotBeforeUpdate).
  • Only happens if shouldComponentUpdate returns true.
  • If you use setState here, you should guard it or you will land in an infinite loop.

shouldComponentUpdate(nextProps, nextState)

  • Only for performance optimization.
  • If it returns false, then a render will NOT be invoked.
  • PureComponent can be used instead if the overridden SCO is just shallow props/state comparison.

getSnapshotBeforeUpdate()

  • Can be used for keeping some information about current DOM, e.g., current scroll position which later can be reused within componentDidUpdate to restore the position of the scroll.

componentDidCatch(error, info)

  • A place where logging errors should happen.
  • Can call setState, but in future releases, it will be dropped in favor of the static method getDerivedStateFromError(error), which will be updating the state by returning a value to update the state.

There are two extra methods that both are static and were mentioned in other explanations

static getDerivedStateFromError(error)

  • Error information is available here.
  • Should return an object value that will update the state which can be used for handling errors (by displaying something).
  • As it is static, it doesn’t have access to the component instance itself.

static getSnapshotBeforeUpdate(props, state)

  • Should be used in cases where props change over time—as an example, according to React docs, it might be useful for a transition component.
  • As it is static, it doesn’t have access to the component instance itself.

Note, there are few more methods that are available as of today, but they are supposed to be removed in React 17.0, so that’s why they weren’t mentioned here.

State vs. Props

Let’s start with Props, as they are easier and faster to explain. Props are properties that are passed to the component which later can be reused within it for displaying information/business logic and such.

import React, { Component } from 'react';

export default class App extends Component {
   render() {

       return (
           <div>
               <HelloWorld name="Someone :)"/>
           </div>
       );
   }
}

const HelloWorld = (props) => <div>Hello {props.name}</div>

In the above example, name is a prop. Props are read-only elements and cannot be changed directly in child components. Also, there is one bad practice that people often do, and that is copy props to the state and operate on the state afterwards. Of course, there are cases where you want to do something like “initial state that will update parent component after submit,” but that’s more rare—in such a scenario, the initial state feeding might make sense. Also, not only properties like strings can be passed to child components, but also numbers, objects, functions, etc.

Props have also one more useful thing which is called defaultProps, a static field which can tell you what the default props are for a component (when they are not passed down to the component, for example).

In case of “lifting state up,” where one component (the parent) has a state which is later being reused by its children (e.g., one child displays it and another allows editing), then we need to pass the function to child from parent, which allows us to update the parent’s local state.

State, on the other hand, is a local state that can be modified, but indirectly by using this.setState. If someone would mutate the state directly, the component will not be aware of the change and it won’t be rerendered to reflect the mentioned changes to the state.

SetState is a method to change local state object (by doing a shallow merge), and after that, the component responds that by rerendering itself. Be aware that after setState is used, the this.state property won’t reflect the changes mentioned in function right away (it has an asynchronous nature) as a few instances of setState might be batched together due to optimization. It has a few ways to be invoked where one of these possibilities allows us to do something with the component right after updating the state:

  • setState({value: ‘5’})
  • setState((state, props) => ({value: state.name + “‘s”}))
  • setState([object / function like above], () => {}) – this form allows us to attach callback, which will be invoked when the state will reflect the data that we wanted to have (in the first argument).
import React, { Component } from 'react';

export default class App extends Component {
   state = {
       name: 'Someone :)'
   }

   onClick = () => this.setState({ name: 'You' })

   render() {
       return (
           <div>
               <HelloWorld name={this.state.name} onClick={this.onClick}/>
           </div>
       );
   }
}

const HelloWorld = (props) => <div onClick={props.onClick}>Hello {props.name}</div>

React Context

React recently stabilized Context API (which was in React for quite some time, but was an experimental feature despite being widely used by some of most popular libraries like Redux), which helps us solve one issue: props drilling. Props drilling in short is a way to pass props deeply within the structure—e.g., it can be some kind of theme for components, localization for specific language, user information, and so on. Before Context (or rather before it became non-experimental), it was drilled down by passing in a recursive way from parent to child through to the last leaf (obviously there was Redux which also could solve the issue). Be aware that this feature solves ONLY props drilling and isn’t a replacement for things like Redux or Mobx. Obviously, if you were using a state management library only for that, then you can replace it freely.

Wrapping Up

This concludes the first part of our React tutorial. In upcoming articles, we hope to tackle more advanced topics, ranging from styling and checking types, to production deployment and performance optimization.

Understanding the Basics

What is React?

React is declarative view library that originated from Facebook and gained popularity over the past few years. Skills honed in the web version can also be easily translated to its native version for mobile apps, i.e. React Native.

About the author

Kamil Jakubczak, Poland
member since June 17, 2017
Kamil is a React, React Native, and JavaScript enthusiast (with a small dose of .NET experience). He recently became hooked by mobile development, deployment, and whatever is needed for it, mostly due to React Native being superb and fun to work with. [click to continue...]
Hiring? Meet the Top 10 Freelance React.js Developers for Hire in January 2019

Comments

Lutaaya Huzaifah Idris
Great
kngfu_sciencexpress
Lol this wasn't a valid comparison, just another "use react because I use it because it's popular".
Javier Ojeda
Can you provide a better comparison article? :)
Ramshah Akbar
So much to learn
comments powered by Disqus
Subscribe
Free email updates
Get the latest content first.
No spam. Just great articles & insights.
Free email updates
Get the latest content first.
Thank you for subscribing!
Check your inbox to confirm subscription. You'll start receiving posts after you confirm.
Trending articles
Relevant Technologies
About the author
Kamil Jakubczak
JavaScript Developer
Kamil is a React, React Native, and JavaScript enthusiast (with a small dose of .NET experience). He recently became hooked by mobile development, deployment, and whatever is needed for it, mostly due to React Native being superb and fun to work with.