Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

React.js for Noobs

DZone's Guide to

React.js for Noobs

React has quickly become one of the most popular libraries/frameworks for web development. Read on to learn how to build your own React app!

· Web Dev Zone ·
Free Resource

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

React.js has been popular among web app developers recently and a lot of websites has adopted the library because of the perks it provides. This post is not about pros and cons of the React.js library, although you can find a myriad of articles and posts on the web comparing React.js with other front-end frameworks.

In layman’s terms, React.js is a JavaScript library which handles the view component of the MVC architecture. React.js is used to manipulate the DOM of a webpage in an efficient manner to render a web application.

Creating a Hello World App

First, let’s create our sample React app. For this tutorial, you need Node and NPM to be installed in your environment. After that, execute the following command to install the react boilerplate app creator.

npm install -g create-react-app 

Next, we can create our hello world app using the below command.

create-react-app hello-world 

Now if we look at the file structure within the hello world app, there are three important files. Those are public/index.htmlsrc/index.js, and src/App.js files. In the index.html file, you can see that there is a div with the id root and in the index.js file there's the below code segment.

ReactDOM.render(, document.getElementById(‘root’)); 

This is the starting point of our app. Basically, React will inject out app component into the div with the root id. Now you might be wondering, what is the app component? If you look at the App.js file, you will be able to see the app component. In React, it is the convention to name JavaScript files with the same name as the component.

React Component

Now let’s look at a React component.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div className="greeting">
        <h1> Hello World! </h1>
      </div>
    );
  }
}

Above is the simplest component we can write in React. We can create a JavaScript class for our component and extend it from the Component class from the React library (Note the import statement). After that, we need to implement the render() method. Prior to React 16, it was a must to return a single element from render method. But with React 16, we can return an array of elements. Now, if we execute an npm start command within the hello world directory, we can see that 'Hello World' is rendered in http://localhost:3000

Figure1: Hello WorldReact JSX (Syntactic Sugar for JS)

In the render method of the component, we can almost use the HTML syntax. But in reality, this is actually JavaScript, specifically known as JSX. JSX is a template language which has a similar structure to HTML with the full power of JavaScript. Hence, you can evaluate any JavaScript statement within the render method.

As an example, the JSX code we wrote earlier (shown below)

const element = 
(
    <h1 className="greeting">
        Hello, world!
    </h1>
);

will be compiled into the JavaScript code shown below.

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

In reality, JSX was introduced to make developers' lives easier by providing a familiar syntactic sugar.

State vs. Props

Now let’s create another component named Alice under the src/Alice.js file. The content of the Alice component would be as below.

import React, { Component } from 'react';

class Alice extends Component {
  render() {
    return (
      <div>
        <h2> Hi, I am Alice </h2>
      </div>
    );
  }
}

export default Alice;

Now we can include this Alice component as a child component in our App component as shown below.

import React, { Component } from 'react';
import Alice from './Alice';

class App extends Component {
  render() {
    return (
      <div className="greeting">
        <h1> Hello World! </h1>
        <Alice/>
      </div>
    );
  }
}

export default App;

Note the new import statement for the Alice component. Without that, our app will break since React is unable to find the component which corresponds to the Alice tag.

Next, let’s see how we can manipulate the state of our components. For each React component, there is a state and by manipulating the state object we can change the behavior of our component. This state object is specific to the component.

import React, { Component } from 'react';
import Alice from './Alice';

class App extends Component {

  constructor() {
    super();
    this.state = {
      greeting: "Hello World!"
    }
  }

  render() {
    return (
      <div className="greeting">
        <h1> {this.state.greeting} </h1>
        <Alice/>
      </div>
    );
  }
}

export default App;

As shown above, we can declare the state object within the constructor (note that it is a must to call super() within the constructor of a React component). This state object contains the  greetings property with the value “Hello World!” In the render method, we have used this property as {this.state.greeting}, and this is the usual way of evaluating JavaScript expressions within JSX. You can add as many properties as you want to the state object. Now let’s see how we can pass data from the App component into its child component, Alice.

import React, { Component } from 'react';
import Alice from './Alice';

class App extends Component {

  constructor() {
    super();
    this.state = {
      greeting: "Hello World!",
      parentMessage: "Hello Alice!"
    }
  }

  render() {
    return (
      <div className="greeting">
        <h1> {this.state.greeting} </h1>
        <Alice newMsg={this.state.parentMessage} />
      </div>
    );
  }
}
export default App;

In the modified App component (shown above), I have added another property named parentMessage and passed it to Alice component as shown below.

  • <Alice newMsg={this.state.parentMessage} />

Note that newMsg is the key I’ve used to pass the data and, for that, you can use any valid string. Now, let’s look at the corresponding Alice Component.

import React, { Component } from 'react';

class Alice extends Component {

  constructor(props) {
    super(props)
    this.state = {
      greeting: props.newMsg
    }
  }

  render() {
    return (
      <div>
        <h2> {this.state.greeting} </h2>
      </div>
    );
  }
}

export default Alice;

If you look at the constructor of the Alice component, there is a method argument named props. This object contains all the data passed from the parent component (input from parent component to the child component). I have initialized the state of the Alice component using the newMsg property passed from the App component. If you have used another string as the key instead of newMsg, you can access it with the following pattern: props.newMsg.

Now the app should be rendered as shown below (Figure 2).

Figure 2: Modified App

The below table summarizes the basic differences between state and props objects of a component.

Image title

Another very important thing to note is that whenever we want to modify the state object, we do it through the this.setState() method, as shown below.

import React, { Component } from 'react';
import Alice from './Alice';

class App extends Component {

  constructor() {
    super();
    this.state = {
      greeting: "Hello World!",
      parentMessage: "Hello Alice!"
    }

    setTimeout(() => {
      this.setState({greeting : "Hello World Updated!"})
    }, 10000)
  }

  render() {
    return (
      <div className="greeting">
        <h1> {this.state.greeting} </h1>
        <Alice newMsg={this.state.parentMessage} />
      </div>
    );
  }
}
export default App;

In the constructor, I have added a timeout function which modifies the greeting message to “Hello World Update!” after 10 seconds. DO NOT use  this.state.greeting = “Hello World Updated!” to update the state as it would not work since React uses an event-driven approach rather than using dirty checking to maintain the state of React components.

React Component Lifecycle

React provides highly valuable lifecycle hooks (method) for each state of the component as listed below. These methods can be classified into 3 categories: mountingupdating, and unmounting.

Mounting hooks are fired when the React component is initially being rendered in the browser page. The below methods are fired in the specified order.

  1. constructor()  - Invoked when creating the React component for the first time.

  2. componentWillMount() - Invoked before adding the component to the actual DOM of the web page.

  3. render() - Invoked when adding the component to the actual DOM.

  4. componentDidMount() - Invoked after adding the component to the actual DOM.

Updating methods are invoked when the component is re-rendered on the web page. This happens due to changes in state/props objects. The elow methods are invoked in the specified order.

  1. componentWillReceiveProps(newProps) - This method is invoked when new props are received from the parent component. Note that this method will not be invoked at the initial time when the component is created even though parent component passes props. The initial time should be handled within the constructor.

  2. shouldComponentUpdate(nextProps, nextState) - This method is invoked before the component is re-rendered. It is a must to return a boolean from this method. If true is returned, the component will be re-rendered and the component will not be re-rendered if false is returned.

  3. componentWillUpdate() - This method is invoked before the component is re-rendered in the actual DOM.

  4. render() - Invoked when the component is re-rendered in the actual DOM.

  5. componentDidUpdate() - Invoked after the modified component is re-rendered on the actual DOM.

As for the unmounting, there is one hook named componentWillUnmount(). This method is invoked immediately before the component is removed from the actual DOM. Apart from that, starting with React 16, there is another lifecycle hook named componentDidCatch() which will be invoked when there is an exception during any of the lifecycle hooks of the component. This method can be used to gracefully show an error message when a React component fails to function as expected. For more information on the component lifecycle events, take a look at the awesome React documentation.

Virtual DOM vs Real DOM

When applying the changes of a React component to the actual web page, React uses a virtual DOM to calculate the changes and then apply only the modified bits into the real DOM. Since React completely builds the virtual DOM, you might be wondering, why not build the actual DOM instead? Re-building the actual DOM is quite expensive since the browser needs to re-calculate all the CSS properties, re-draw the canvas, and fire all the event listeners unnecessarily. Hence, building the virtual DOM and applying only the difference to the actual DOM is quite efficient and this process is known as reconciliation. React implements a heuristic based algorithm to calculate the difference between the virtual and actual DOMs, which has a time complexity of O(n).

As an example, when rendering a component, initially both DOMs are empty (Figure 3).

Figure 3: Empty DOM

First, the virtual DOM is populated with the content (Figure 4).

Figure 4: Virtual DOM population

Next, the real DOM is populated with the content and the virtual DOM is cleared (Figure 5).

Figure 5: Actual DOM population

After that, for any change, the complete virtual DOM is generated with the newly modified content (Figure 6).

Figure 6: Re-creation of Virtual DOM

Next, the difference is calculated and only the modified section is updated in the real DOM and the virtual DOM will be cleared (Figure 7).

Figure 7: Updating real DOM

This sums up for the basic introduction to the React.js and it is time for you to get your hands dirty and start building your first React app to get some first-hand experience. In the next blog post let’s see how we can craft an elegant data flow between React components using Flux. Until then, happy coding!

What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

Topics:
web dev ,react.js ,web application development ,javascript libraries ,javascript frameworks

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}