The latest version of this text can be found at https://info340.github.io/.

Chapter 16 Introduction to React

16.1 Overview

React is a JavaScript library for building user interfaces. Using the React library will enable you to create reusable components that you can combine into robust web applications. We’ll continue the pursuit of using data to drive web applications by using a structure in which we pass different data to components we create.

Because React is such a popular and configurable library, people use it in complex ways in conjunction with a variety of different tools to manage complex applications. We’ll introduce a number of these tools as the course moves forward, but we’ll start as simple as possible – just be aware that some of the examples you find online (even Facebook’s React Tutorial) may leverage additional tools to “simplify” the process.

16.2 React Set-up

Using React is similar to using other JavaScript libraries in that you’ll need to load them into your application to use them. In fact, you’ll need to load 3 different libraries (at this point)

<!-- Read in React scripts -->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<!-- Read in Babel Script -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>

The React library actually consists of 2 libraries that are loaded in the script above. The react.development.js script is the library used to create React components, while the react-dom.development.js library is the library that handels DOM manipulation. The third script that you loaded (babel) is what will allow us to write in a new syntax: jsx.

16.3 JSX

As described in this introductory post, JSX is a syntax extension to JavaScipt. It provides you with a way to write bare HTML tags in your JavaScript (finally!). We need to include the babel script above because your browser won’t understand this syntax (babel will transpile it for you). For example:

// A regular JavaScript constant
const name = "Mike";
// Use JSX to store an HTML element in a JavaScript variable
const element = (
  <h1 className="large">
    Hello, {name}!
  </h1>
);

// Render your element to the DOM in your `root` element
ReactDOM.render(
  element,
  document.getElementById('root')
);

In the above example the element variable stores an HTML element. A few things to note:

  • To include JavaScript variables in your JSX, simply wrap the variables in curly braces (i.e., {name})
  • Because the word class is a protected word in JavaScript, you’ll need to use the JSX alternative className to set the class attribute
  • The ReactDOM.render() method takes in two parameters: the element you want to render, and the element in which to render your element.

16.4 Components

Wouldn’t it be great if we could create our own HTML elements? For example, what if we were able to define a <Tweet> element for a Twitter application? That’s what React will enable us to do. Once we create components, we’ll be able to refer to them as if they were regular HTML elements that we want to render. We’ll leverage JavaScipt’s class inheretence structure to create our own classes that extend the React class. These objects have a render method that return the element to draw on the DOM. For example:

// Create a component that represents someone's bio
class Bio extends React.Component {
    render() {
        return(
            <div>
                <h1>Arthur</h1>
                <p>Hello, my name is Arthur and I am an Aardvark</p>
            </div>
        )
    }
}

// Render our new Bio component:
ReactDOM.render(
  <Bio>,
  document.getElementById('root')
);

A few things to note: - Our class (Bio) must begin with a capital letter - Our render statement can only return one HTML element (though it can contain as many HTML elements as you want)

These Components are powerful because you can pass properties to them (just as you would set the attributes to HTML elements).

16.5 Properties

When you create a React component, you can pass it properties in the same way that you would specify HTML attributes. Properties (or props) are pieces of data that your component can use to display data that it is passed, making it a flexible templating system. The values passed to a component are accessible within the component as this.props. This will allow us to dynamically show information that is passed to the component:

// Define the class Bio to take in `name` and `description` properties
class Bio extends React.Component {
    render() {
        return(
            <div>
                <h1>{this.props.name}</h1>
                <p>{this.props.description}</p>
            </div>
        )
    }
}

// Render our new Bio component:
ReactDOM.render(
  <Bio name="Arthur" description="Hello, my name is Arthur and I am an Aardvark">,
  document.getElementById('root')
);

We are now able to pass in our data of interest as properties. The components that you create have lifecycle methods that help keep the DOM up to date as your data changes. For an overview of these methods, you can see the documentation. For now, it’s important to note that a number of functions are invoked by default when you change your props or your state (more on this below). When your props change, your render method will be called (as will a number of other functions to allow you to control the flow of information).

16.6 Nesting Components

Once we’ve created components, we can render them inside of other components, just like regular HTML elements! This is a core idea to React, as it uses a one-directional data flow where parent components pass data to child components.

Let’s imagine that we want to create a list (pretty simple, right?). For each list item (<li>) that we want to create, we could render a React component (ListItem).

Let’s start by creating a ListItem component:

// Simple ListItem component for showing an <li>
class ListItem exteds React.Component{
    render() {
        return(<li className={this.props.status}>{this.props.text}</li>)
    }
});

The above section is written to accept two properties: status and text. Note, we again have to use className to assign a class.

Now we can create a List component to render all of our ListItem components.

// Data to pass to our List element
let items = [
    {text:"Go to the store", status:"complete"},
    {text:"Go to class", status:'incomplete'}
];

// A component for creating an entire list
class List extends React.Component {
    render() {
        return(
            <div>
                { // Iterate through items + return a ListItem
                this.props.items.map((item, index) => {
                    return <ListItem key={'item-' + index} status={item.status} text={item.text} />
                })
                }
            </div>
        )
    }
}

In the above section, we open up a JavaScript section inside of the <div> element that we’re going to return. We can then access the items via this.props.items and iterate through them with the .map function. Each iteration will return a ListItem.

  • Note: React will issue a warning if you don’t assign each element a unique key to help it identify changes in the DOM.

Finally, we’ll pass our items data to our List component and render it:

// Render your component in the `main` section
ReactDOM.render(<List items={items}/>,
    document.querySelector('main')
);

You should now be able to create simple React components and specify their properties. The power of configuring applications using these properties is discussed more in the following chapters.