Learn React - React Crash Course 2019 - React Tutorial with Examples

  • 2019-02-21 02:15 AM
  • 197

Learn React - React Crash Course 2019 - React Tutorial with Examples

So you’ve probably heard that there is big hype for React these days. You’re curious to find out what it is and why it has a high adoption rate. And you want to quickly learn how to build a simple page using React. If that sounds like you, this post is for you.

If you prefer learning by videos, watch my React tutorial on YouTube; otherwise, continue reading.

What is React?

In my earlier post, I explained that **React is a lightweight library for building fast and interactive user interfaces. **Unlike Angular, which is a framework (or a complete solution), React is essentially a ‘view library’. It only takes care of the view or what is rendered in the DOM. It doesn’t have an opinion about other aspects of an app such as routing, calling HTTP services, etc. For those concerns, you need to use other libraries. This means you get the freedom to choose the libraries that you’re familiar with or prefer.

React Components

Components are the building block of React apps. A component is a piece of UI. It has data and describes what that piece of UI should look like. When building React apps, we build a bunch of small, independent and reusable components and compose them to make complex UIs. So every React app is essentially a tree of components. If you’ve worked with Angular 2+, this should sound familiar.

A Real-world Example of React Components

Imagine you want to build a web application like Twitter. Head over to Twitter’s website and you’ll see various pieces like below. We can implement each of these pieces as a React component.

React Tutorial

Our component tree in this example could look like this:

  • App
    • NavBar
    • ProfileDashboard
    • Trends
    • WhoToFollow
    • Feed

Components can include child components. For example, the Feed component includes several Tweet components and each Tweet components has a Like component. So, our component tree could be extended to something like this:

  • App
    • NavBar
    • ProfileDashboard
    • Trends
    • WhoToFollow
    • Feed
      • Tweet
        • Like

We can re-use this Like component (or any other components in the tree) on different pages or even in different applications.

A component is typically (but not always) implemented as a JavaScript class that has a state property and a render method. State includes the data that we want to display. The render method describes what the UI should look like.

Setting Up the Development Environment

There are a few things you need to install to get started.

First, head over to nodejs.org and install Node if you already don’t have it on your machine. We don’t need Node to build React apps. We only need one of its tools (Node Package Manager or NPM) to install React and other libraries. You’ve probably used NPM before.

Second, you need a code editor. Feel free to use any editors you prefer. My preferred editor is Visual Studio Code/VSCode which you can get from code.visualstudio.com

Now, open up the Terminal on Mac or Command Prompt on Windows and run the following command to install **create-react-app **package. We use this package to bootstrap new React apps:

npm i -g [email protected]

Make sure to use the same version I’m using here even if there is a newer version available. I just want to make sure you can follow this tutorial all the way to the end.

If you’re on a Mac and haven’t configured the permissions properly, you need to prefix this command with **sudo: **

sudo npm i -g [email protected]

Creat Your First React App

Now, type the following command to create a new react app:

create-react-app my-app

This command will create a new project with all of the required dependencies. It’s the fastest way to get a React app up and running with zero-configuration. You don’t have to configure Webpack, Babel, and other tools as create-react-app takes care of all of them.

Now, go to the project folder and start your React app:

cd my-app

This will start a development web server on port 3000 on your machine. It’ll also launch your browser navigating to http://localhost:3000. You see your first React app here.

React Tutorial

Project Structure

Let’s see what we have in this project. We have 3 folders:

  • node_modules: where all the 3rd-party dependencies (libraries) are stored. We never have to touch this.
  • public: where we have public assets of our app such as index.html, logo, images, etc.
  • src: where we have the source code of our React app.

Open up **package.json. **Chances are you’re already familiar with this file. If not, package.json is like an identification card for a project. It includes the project’s name, version, dependencies, etc.

Note that under dependencies, we only have 3 dependencies:

{
  "dependencies": {
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-scripts": "1.1.4"
  },
}

In reality, there are several other dependencies behind the scene that you don’t see here. We need

  • Webpack for bundling our JavaScript files,
  • Babel to compile the modern JavaScript code into code that most browsers can understand,
  • ESLint for linting our JavaScript code, which basically means making sure there are no syntactical issues and the code is clean and consistently formatted.
  • Plus many other libraries…

The beauty of create-react-app is that it hides all these from us. So, we never have to manually configure all these tools which can sometimes be a pain in the neck. So, you can get started in a matter of seconds.

But what if you want to customize the configuration for these tools? Well, you’ll need to “eject” from create-react-app. You simply run:

npm run eject

And create-react-app will then add all those dependencies to package.json. It’ll also create a couple of additional folders in your project where you can see the actual configuration and customize it.

Remember: Ejecting is a one-way street. Once you do it, there is no way to go back to that clean configuration in package.json.

Hello World!

Now, delete all the files inside of the **src **folder. We’ll write all the code from scratch. Create a new file called **index.js **and write the following code:

import React from 'react'; 
import ReactDOM from 'react-dom'; 

const element = <h1>Hello World</h1>;

ReactDOM.render(element, document.getElementById('root'));

Save the changes. Here we have Hot Module Reloading (HMR). That basically means that whenever we change any of our files, our React app will automatically restart in the browser. We don’t have to manually refresh the page. Switch back to your browser, and you should see the Hello World message on the page!

Analysis of the Code

Now, let me explain what is going on here.

On the first 2 lines, we are importing a couple of React objects from their corresponding module.

import React from 'react'; 
import ReactDOM from 'react-dom'; 

Modules are introduced in ES6 or ES2015 which is a modern version of JavaScript. With modules, we can modularize our code into multiple files. Instead of writing all the code in one gigantic file, we split it across multiple files so our code is more maintainable. We call each file a “module”. Then, we can import one or more objects from a module and use it in another module.

On line 4, we are defining a constant (which is another new feature in JavaScript) called element. A constant is essentially a variable that cannot be re-assigned. In the old days, we used var.

JSX

Note the value of the element constant. It’s neither a string nor HTML markup. This is what we call a JSX expression. JSX stands for JavaScript XML and it’s an extension to JavaScript. We use it to describe what the UI looks like. We’re all familiar with the HTML syntax, so we use the same syntax in JSX expressions but there are additional features available to us for dynamically rendering data.

Now, obviously, browsers don’t understand this new syntax and chances are they never will. So, we have to run this code through a compiler (Babel) and convert it into something that browsers can understand. The result of compiling that code will be something like this:

var el = React.createElement(
  'h1',
  null,
  'Hello World'
);

We could write this code by hand to describe the UI (in this displaying “Hello World” using an H1 element). But as you see, writing code like this is tedious and error-prone. Plus, it’s hard to figure out what the UI really looks like when dealing with complex markup with nested elements. It’s much easier to use a JSX expression:

const element = <h1>Hello World</h1>;

React Elements and Virtual DOM

Now, the value of this element at runtime will be a React element which is a plain JavaScript object that represents a DOM element. It’s not an actual DOM element. It’s just a plain JavaScript object that describes that.

So, React keeps a lightweight representation of the real browser DOM in memory which is called the Virtual DOM. Whenever the data in our application changes, a new React element is created in memory. React will compare this element with its previous version, it figures out what data is changed, then it’ll reach out to the DOM and update specific elements to match the Virtual DOM.

Say Goodbye to DOM API

So, this means, in React apps, we don’t have to work with the DOM anymore. You never have to assign IDs and classes to DOM elements, query them, manipulate them, attach event handlers, etc:

var element = document.querySelector('#course');
element.classList.add('...');
element.eventListeners.add(...);

We only work with React elements and components. We change the data or state of our components, React figures out what is changed and it’ll automatically update the DOM to match the state.

Rendering React Elements

Finally, the last line of our code:

ReactDOM.render(element, document.getElementById('root'));

Here, we’re using the ReactDOM.render() method to render this element in the DOM. Where in the DOM? Inside the element with the ID ‘root’. Where is this? Open /public/index.html. In the body section, you should see a div like this:

<div id="root"></div>

This is the container for our React app. In this example, we’re rendering a simple React element (h1) in this container, but in a real-world app, we’ll render a component. This component is called the root component and it wraps the entire app. It is on top of a tree of components. With this tree, we can render a complex UI in the DOM.

Your First React Component

Earlier I told you that components are the building blocks of React apps. But where is a component in this example? We haven’t defined one yet.

As I mentioned before, a component is a piece of UI. On this piece, we can have a single element (like an h1 element), but quite often we have a complex markup. That is the whole point of a component. We want to break down a complex UI into a bunch of small and maintainable components.

Now, let’s build a simple component.

Inside the **src **folder, add a new file: **counter.jsx. **You could use the **js **extension, but if you’re using Visual Studio Code, when you give a file the **jsx **extension, you get better syntax highlighting and code completion.

Type the following code and then I’ll break it down for you:

import React, { Component } from 'react'; 

export default class Counter extends Component { 
   state = { value: 1 }; 

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

Analysis of the Code

Once again, on the top, we’re importing the React object from the ‘react’ module. But, we’re not using that object anywhere in this code. So why do we have to import it? Earlier I told you that our JSX expressions get compiled to calls to React.createElement(). That’s why we have to import React on the top.

Next, we’re defining a class called Counter and exporting it. The objects we define in a file (module) are private or invisible to other modules by default. When we export them, other files (modules) can import and use them. Every module can have a default export. That is the main object that is exported from that module.

This class has a state property which holds the data that we want to display.

The render() method returns a JSX expression which is essentially a React element. Note that here we are using curly braces in our JSX expression:

<div>{ this.state.value }</div>

Whenever we use curly braces in a JSX expression, we can pass values dynamically. In between the braces we can write any valid JavaScript expressions. An expression is something that produces a value. We can write an expression like:

{ 2 + 2 }

So, 4 will be rendered in the DOM. Or, we can call a function that returns a value:

{ this.getValue() }

Using a Component

Now we have a component that renders the value of a counter. In this example, we’re using a single div. In a real-world scenario, we could have some fairly complex markup with nested elements and Bootstrap classes to make our app look pretty.

Let’s use our new Counter component. Open up index.js, import the Counter component on the top, and then modify the last line to render the Counter component instead of the element we created earlier:

import Counter from './counter'; 
...
ReactDOM.render(<Counter />, document.getElementById('root'));

See how we have used our Counter component? It kind of looks like we have extended the HTML vocabulary. We have encapsulated the concept of a counter behind an element like . Note that in JSX, if there is nothing between the opening and closing tags, you should use the self-closing notation.

Save the changes. You should our counter value displayed on the page.

Handling Events

Now, let’s take this to the next level and add a button to our Counter component. Whenever we click this button, the value of the counter gets incremented. So, back to **counter.jsx, **modify the render method as follows:

render() {
   return (
      <div>{ this.state.value }</div>
      <button onClick={() => { console.log('clicked'); }>Increment</button>
   );
}

A couple of things to note: we have surrounded our JSX expression with parenthesis for breaking them down into multiple lines. If you don’t put parenthesis here and have a return keyword by itself on a line, JavaScript automatically inserts a semicolon after the return. So, nothing will be returned. To fix this issue, we have to wrap our multi-line JSX expressions with paranthesis.

Here, we have set the onClick attribute of the button to an expression. This expression is an arrow function. If you’re not familiar with them, be sure to read my post 4 Modern JavaScript Features You Should Be Using Now.

With this code, whenever we click this button, we should see a **clicked **message in the console. Save the changes and try it for yourself.

Updating the State

So, we got the button to do something when we click it. Next, we need to increment state.value. In React, we don’t update the state directly. In other words, we should not write code like this:

this.state.value++;

You may ask why? This is a long discussion, but basically React is designed with functional programming concepts in mind. One reason for this is that if we update the state directly, React will not be able to figure out what is changed, so it won’t know what part of the DOM to update. Another reason we don’t update the state directly is for performance reasons. Again, this is a topic for another post. For now, just take this from me: to update the state, we call the setState method of our components. You saw that our Counter component extends the Component class in React. By extending a class, we inherit all the functionality defined in that class. One of the methods defined in the Component class in React is the setState method.

So, modify the render method as follows:

render() {
    return (
        <div>
            <div>{ this.state.value }</div>
            <button onClick={() => { this.setState({ value: this.state.value + 1 }) }}>Increment</button>
        </div>
    )
}

Here, we call the setState and pass an object. The properties in this object will overwrite the properties in our state property or merge with them. With this, we can increment state.value.

Note: Whenever we write a component, all of our code must be encapsulated inside of a parent element, such as a

. This is because when our code is compiled, each component must return only one parent component. So in our example, if we do not do this, the button tag would be unreachable.

Now, save the changes. Go back to the browser and click the Increment button. Note that the value of the counter is now increasing by one with each click.

How React Works

You saw that our Counter component has a state. This is the data that we want to render in the DOM. We attached a handler to the click event of a button. When we click this button, we call the setState method. This will, in turn, update the state of our component. React will be notified. It figures out what element in the virtual DOM is updated. Then, it’ll update the real DOM to match the virtual DOM. We never had to get a reference to a DOM element (in this case the div) and set its innerText property.

Did you enjoy this post? If yes, please share it on social media. Feel free to drop your comments below.

Want to learn more?

This was a short and sweet introduction to React. There is more to React when it comes to building real-world applications. That’s why I’ve created a comprehensive React course. In this course, you’ll learn everything about React and build a real video rental application throughout the course. So, you’ll see all the moving parts coming together. More specifically you’ll learn all about:

  • Components
  • Tables with pagination, searching, sorting
  • Forms with validation
  • Routing and navigation
  • Calling backend services (APIs)
  • Authentication and authorization
  • Deployment
  • And more…

Modern React with Redux

Become a JavaScript developer - Learn (React, Node,Angular)

The Complete React Web Developer Course (2nd Edition)

Node with React: Fullstack Web Development

Beginner Full Stack Web Development: HTML, CSS, React & Node

React JS and Redux - Mastering Web Apps

React 16 - The Complete Guide (incl. React Router 4 & Redux)

MERN Stack Front To Back: Full Stack React, Redux & Node.js

Originally published at https://programmingwithmosh.com

Suggest