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 alternativeclassName
to set theclass
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.