React js

Javascript has become my flesh and bones and the blood that circulates in my body contains the various concepts it offers that keep me alive. So, am I a robot? No, its just I love Javascript so much and React JS :).

Javascript frameworks have become an integral part of developing applications due to their robustness and simplicity. I have had the opportunity to work in some of the frameworks like Angular JS, React JS and Ember JS. But I’m specifically fond of React JS. 

In this article, I’ll be explaining some of the concepts that make React JS a go-to framework and also its learning curve.

The Learning curve

Every expert was once a beginner

Literally any expert

Learning takes time and no one can deny that. But it also depends on an individual. For some, it takes months to learn something new whereas, for others, it only takes weeks. For me, who already has some knowledge of Angular JS and some extra knowledge on vanilla JS, it took about a month to understand how React JS works.

It took me a month because I was working with Angular JS previously and it differs a lot from React JS and so switching from one framework to another takes extra time, effort and a lot of confusion. If you are new to JS frameworks but you have some knowledge on plain JS, it may take you less than a month.

Also, I recommend you to check out my post on Javascript ES6 features since React JS also uses ES6.

Basics of React JS

React JS is a javascript library that can be used for building user interfaces. It was created by Facebook and its first version was released in May 2013 for the public to use. Now the stable version is 16.12.0 (at the time of writing this article). 

Note that, React JS can only be used to develop the UI part of an application. You need to use some backend languages like Java or Python to create a full-fledged application. So basically, React JS is a UI library per se and not a framework.

So what makes React JS special? What does it offer that the other frameworks don’t? Let’s explore.

Virtual DOM

The first and foremost thing that makes React JS unique is the concept of Virtual DOM. According to the official React documentation:

The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM.

DOM is basically a tree of objects that define the structure of an HTML page. Generally, whenever a change happens, say adding or deleting of elements, the entire DOM is reconstructed to reflect the changes. This is fine for smaller applications. But in larger applications, this is time-consuming since they have a larger DOM.

Virtual DOM overcomes this problem by creating a copy of the DOM when a change happens. It then compares it with the original DOM and updates only the elements that have changes This process is termed as reconciliation. Since it only updates the elements that have changed, this improves performance in web applications.

JSX

Consider this code which can be used to create an <h1> element dynamically using javascript.

var animal = document.createElement("h1");
h1.appendChild(document.createTextNode("Hello React”));

If you have been working with JS and HTML for some time, you will definitely feel the tension when seeing this code. So how can we make it easier? JSX comes to the rescue.

JSX refers to Javascript (JS) and XML (X). Using JSX, we can easily integrate HTML with JS. Here’s an example.

const animal = <h1>Hello React</h1> ;

Simple, isn’t it? JSX can also be used with expressions such as this:

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

Neat huh? But JSX is optional. Every JSX statement compiles to React.createElement() method.

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

You can’t say no after seeing how JSX can simplify your code right? Then you better use it.

State and Props

A State can be inferred as a container that contains the properties used by a component. It is private inside a component and is fully controlled by the component.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
}

In order to change the values of properties inside a state, React recommends a method known as setState(). 

this.setState({
  date: new Date()
});

Calling the setState() method trigger re-render. But keep in mind that, calling setState() multiple times does not trigger re-render multiple times rather, it batches the state updates into a single setState() call. 

The only caveat to this is that batching occurs only when setState() is called during React’s synthetic events and lifecycle methods and not on setTimeout() and AJAX calls.

Also, avoid trying to set state variables directly since it does not cause a re-render like setState().

this.date = new Date(); // Wrong

Props are a way of communicating between components. For example, if you want to send some data from the parent component to a child component, it can be done using props.

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

const element = <Welcome name="Sara" />;

In this example, name is a prop. It can be accessed inside the Welcome component using this.props.name

Components

What do you say when a teacher asks you “What is the use of a function in javascript?”. The only answer that comes to our mind is “Reusability”. Components are similar but a bit advanced than regular functions. They get props as inputs and return what we want them to.

There are two types of components in React, function component and class component. 

Function components are stateless components, i.e, they don’t have states which we saw earlier. They are pure functions that return the same output for the same input given and accept props.

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Class components are stateful components i.e they can have states. It has the ability to use lifecycle methods that are available to React by default. 

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

If you are not familiar with Classes, then I recommend you to come back here after going through this article where I have explained in detail various ES6 features including Classes.

Lifecycle methods

Every component has a cycle of life and it starts from getting created when used and being destroyed when not needed. These are handled by some of the built-in methods provided by React and are called Lifecycle methods.

The lifecycle methods follow an order of execution and are divided into four phases. They are:

  1. Mounting 
  2. Updating
  3. Unmounting
  4. Error handling

Mounting

  • constructor() – Use this method if you want to initialize state variables or bind methods
  • static getDerivedFromProps(props, state) – Invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.  
  • render()a method that is required when using class components
  • componentDidMount() – is invoked immediately after a component is mounted (inserted into the tree). 

Updating

  • static getDerivedFromProps(props, state) 
  • shouldComponentUpdate()You can return either true or false if you want to component to render or not. Returns true by default.
  • render()
  • getSnapshotBeforeUpdate(prevProps, prevState) Invoked right before the most recently rendered output is committed to e.g. the DOM. Any value returned by this lifecycle will be passed as a parameter to componentDidUpdate().
  • componentDidUpdate() Invoked immediately after updating occurs. This method is not called for the initial render.

Unmounting

  • componentWillUnmount Invoked immediately before a component is unmounted and destroyed.

Error Handling

  • getDerivedStateFromError(error) Invoked after an error has been thrown by a child component. It gets called during the “render” phase and hence side-effects are not allowed
  • componentDidCatch() – Invoked after an error has been thrown by a child component. It gets called during the “commit” phase and hence side-effects are allowed.

Higher-Order Components (HOC)

This is a slightly advanced concept but it’s better if you know what it is. HOC’s are components that take a component as an input and returns another component. Let’s look at an example.

Say, there is a component Person1 who does some follow a schedule every day.

class Person1 extends React.Component {
  constructor(props) {
    super(props);
    this.wakeUp = this.wakeUp.bind(this);
    this.state = {
      tea: Record.getTea(props.name)
    };
  }

  componentDidMount() {
    Record.addChangeListener(this.handleChange);
  }

  componentWillUnmount() {
    Record.removeChangeListener(this.handleChange);
  }

  wakeUp() {
    this.setState({
      tea: Record.getTea(this.props.name)
    });
  }

  render() {
    return <DoesYoga name={name} />;
  }
}

Later, you write another component Person2 who has a similar schedule.

class Person2 extends React.Component {
  constructor(props) {
    super(props);
    this.wakeUp = this.wakeUp.bind(this);
    this.state = {
      coffee: Record.getCoffee(props.name)
    };
  }

  componentDidMount() {
    Record.addChangeListener(this.wakeUp);
  }

  componentWillUnmount() {
    Record.removeChangeListener(this.wakeUp);
  }

  wakeUp() {
    this.setState({
      coffee: Record.getCoffee(this.props.name)
    });
  }

  render() {
    return <GoesRunning name={name} />;
  }
}

Both Person1 and Person2 have similar schedules but they return different outputs. This can be simplified using HOC’s. We can write functions that create a component that subscribes to a Record and pass the components as props.

const Person1Schedule = personSchedule(
  Person1,
  (Record, props) => Record.getTea(props.name)
);

const Person2Schedule = personSchedule(
  Person2,
  (Record, props) => Record.getCoffee(props.name)
);

Now the personSchedule component can be written as:

// This function takes a component
function personSchedule(PersonWrapped, recordData) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.wakeUp = this.wakeUp.bind(this);
      this.state = {
        data: recordData(DataSource, props)
      };
    }

    componentDidMount() {
      Record.addChangeListener(this.wakeUp);
    }

    componentWillUnmount() {
      Record.removeChangeListener(this.wakeUp);
    }

    wakeUp() {
      this.setState({
        data: recordData(DataSource, this.props)
      });
    }

    render() {
      // Note that we pass through any additional props
      return <PersonWrapped data={this.state.data} {...this.props} />;
    }
  };
}

This makes it easy to reuse component logic as many times as you want. Also, note that we don’t modify the component that we pass as input. Therefore, a HOC is a pure-function without any side-effects. Refer React docs for more information on HOC’s.

Refs

In React, props are the only way to pass data from a parent component to a child component. And since props are read-only, you need to send changed props if you want the child component to re-render. React provides another way of doing this using refs.

You can create a ref using the React.createRef() method and assign it to elements using the ref attribute.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

According to React documentation:

There are a few good use cases for refs:

  • Managing focus, text selection, or media playback.
  • Triggering imperative animations.
  • Integrating with third-party DOM libraries.

You can also use refs to access child elements from parent elements. Even though this is not recommendable in most cases, sometimes you might want to trigger an event in child elements or change the position of a child DOM node. Please refer to the official React JS documentation for more details on refs.

Hooks

Hooks are a recent addition to React from version 16.8. They can be used to add state and other React features without using a class. I’ll be covering only the basics of hooks. Once you understand this, you can look for more details in the React docs.

There are two types of hooks: state hooks and effect hooks.

State hook

State hooks are used to add states to a function component.

import React, { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Here useState() is a hook and we can use it inside function components. It is always declared as a pair: a state variable count and a method name setCount that can mutate the state variable.

It’s not a convention that the method name should be the same as the state variable but with a prefixed “set”. You can use any name you want. Refer React docs for detailed implementation of state hooks.

Also, remember that Hooks does not work on class components. 

Effect hook

Effect hooks are used to perform side-effects on function components.

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Here useEffect is a hook. If you can recall the lifecycle methods we have seen earlier, then useEffect is a combination of componentDidMountcomponentDidUpdate, and componentWillUnmount methods. Since function components do not support lifecycle methods, useEffect will be called in place. For a detailed explanation, refer to React docs.

Conclusion

Here we are at the end but don’t stop just here. Like I said at the beginning, I have only covered the basics that will help you kickstart your React JS career.

The React docs have a detailed explanation of each of the topics I have gone through and also much more. So check that out if you want to become a full-fledged React JS developer.

Hope you found the article helpful. Feel free to comment on why you chose React JS over other JS frameworks and how easy was it to learn. 

Signing off for now.

Arigato Gozaimasu 🙂

+1

71