React - First steps
April 12, 2017
Hello guys, how are you? Today I’ll talk a little about React, the Facebook front-end library for building user interfaces that have been gaining lots of popularity recently. Well, probably everyone heard about it, and in this post I’ll talk about how React works, and how you can give your first steps with it and create a web application.
At the end of this post, you can find the final code on a Github repository.
What is React
Facebook, React’s creator, define React as a Javascript library for building user interfaces, presenting as the main selling points that it is declarative, component based and follows the “Learn once, write everywhere” motto. React also utilizes JSX, a language which is similar to XML, but with some features that make it way easier to build interfaces and componentes. Let’s talk quickly about these three main concepts about React.
Declarative
A usually accepted concept for declarative programming is that, in this style of programming, you define what you want, while normally, in the imperative style, you would define each step, indicating how you would get what you want. The way React works, you define your interface in a declarative way, and we will see how.
Component Based
With React you can create isolated components, each containing its own methods, properties and state, and you can combine them to create complex user interfaces.
Learn Once, Write Everywhere
React does not make any assumptions about your technology stack. You can use React with Django, with Angular, with Rails, combine it with NodeJS. Besides that, it is also possible to create mobile applications using React Native
First Steps with React
Enough of theory and let’s make our first steps. Starting to create with React is easy. First, let’s create a basic structure. A public
folder, with the index.html
file inside it. This HTML file will import three libraries that we will use, which are Babel, React and React DOM. You can import them from CDNJs. Your initial file will be like that:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
This div, with the id of app
, will be the container for your application. This div is where React will render your JSX code, or a component we will create. To render our first JSX content, let’s use the render
method from React DOM. We will pass two parameters to this method. The first one is the JSX code we want to render. The second one is where this JSX code will be rendered. In this case, it will be the div with the id of app
. First, let’s render a simple paragraph:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
ReactDOM.render(
First React App,
document.getElementById('app')
);
</script>
</body>
</html>
Let’s use http-server
(talked about it in this post), check it out and search for http-server
) to serve our files. Run the http-server
command and access http://localhost:8080/. You will see the paragraph rendered on your page. Congratulations, you just created your first React application.
A Little bit of JSX
JSX has some more interesting features. First one is that you can embed Javascript code in your component’s template. You just have to put the Javascript code between square brackets ({}
). Let’s modify our example a little bit:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
var today = new Date();
ReactDOM.render(
Hello, 2 + 2 = {2 + 2} and today is day {today.getDate()} of the month {today.getMonth() + 1},
document.getElementById('app')
);
</script>
</body>
</html>
Right there, we embedded Javascript in the middle of our component’s layout, and what you shall see when you access your localhost is something similar to the image below:
Now that we saw how to start, let’s separate things a little. Let’s remove this script from our HTML body
and put it on a separate file. This file will be app.jsx
, which will be on the public
folder, right alongside index.html
. After that, we will define the src
attribute of the script tag in the index.html
to app.jsx
, so it will point to our newly created JSX file, with the code to render the p
element inside the div
. The index.html
file will be like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="app.jsx"></script>
</body>
</html>
And the app.jsx
will be like this:
var today = new Date();
ReactDOM.render(
Hello, 2 + 2 = {2 + 2} and today is day {today.getDate()} of the month {today.getMonth() + 1},
document.getElementById('app')
);
Ok. Now we have our HTML and our Javascript code separated in two different files. Let’s create our first component.
Our First React Component
For the creation of components, you will normally see in the tutorial, sites and guides about React, two ways. There is also one way that is not very utilized, and usually is not covered in most guides. Just so that you know about it, this way of creating a component is a function that receives as its parameter the props
object. This object will have information that you want to pass to the component. This function returns JSX code. Basically, something like the example below (which was inspired in the official documentation example :)), which can be put on our app.jsx
file:
var props = {name: 'Felipe'};
function HelloComponent(props) {
return Hello, {props.name}
}
ReactDOM.render(
HelloComponent(props),
document.getElementById('app')
);
props
is an abbreviation for properties. props
, like we said before, is input or data that you want to pass to your component, so it uses this information to render or behave differently.
As for the most used ways, the first, and older one, is the createClass()
method of React. Inside of it, we define the render
method, which indicates what is to be rendered when this component is imported. This method should be used if you do not have access to the latest ES6 features. But, we have Babel, and because of that, we can use the most recent way of creating a component, which recommended by Facebook’s documentation. You create a component extending the ES6 “class” React.Component
. Inside of it, we also have to define the render
method inside of it. And then we pass this component to the ReactDOM’s render
method, with a syntax similar to HTML. Note that you have to close the component with a /
. If you don’t do it, you will get an error. Let’s see in our example:
class HelloComponent extends React.Component {
render() {
return (
This is HelloComponent
);
}
}
ReactDOM.render(
<HelloComponent/>,
document.getElementById('app')
)
To pass props
to the component, we just include them, in the same way we would define a HTML attribute, but inside square brackets, when we use the component. Inside the component, we can retrieve the props
value with this.props
+ the prop name. In the example, we will pass to the component a name prop
:
class HelloComponent extends React.Component {
render() {
var name = this.props.name;
return (
Hello, {name}. This is HelloComponent
);
}
}
ReactDOM.render(
<HelloComponent name={"Felipe"} />,
document.getElementById('app')
)
Now that we talked about components and props
, let’s talk about state
.
Components and state
While props
are passed to a component, state is the actual, current state of the component. Input and data that defines how a component behaves and renders. According to React’s official docs, state is similar to props
, data and information used by component, but totally controlled and managed by it.
To define a component’s initial state, we have to create a constructor for the component, and inside this constructor, we define a value for this.state
, which is an object. Let’s add a counter
to our state, and add a paragraph to render our counter in our render
method, which we will retrieve with this.state.counter
:
class HelloComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0
}
}
render() {
var name = this.props.name;
var counter = this.state.counter;
return (
Hello, {name}. This is HelloComponent
The current counter value is: {counter}
);
}
}
ReactDOM.render(
<HelloComponent name={"Felipe"} />,
document.getElementById('app')
)
Ops, we got an error. If you update your browser and head to the browser’s Javascript console (on Google Chrome, press F12 and click on console), you will see the following error message: Uncaught SyntaxError: http://localhost:8080/app.jsx: Adjacent JSX elements must be wrapped in an enclosing tag (16:12)
. Since this is a good error message, we now know that JSX require that all the elements must be wrapped in a single “parent” element. This is easily solved including a div
that wraps the two paragraphs:
class HelloComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0
}
}
render() {
var name = this.props.name;
var counter = this.state.counter;
return (
<div>
Hello, {name}. This is HelloComponent
The current counter value is: {counter}
</div>
);
}
}
ReactDOM.render(
<HelloComponent name={"Felipe"} />,
document.getElementById('app')
)
If we change our counter definition on row 6, from 0 to 3, for example, and then refresh our browser, we can see this change reflected. Now, let’s create a button in our component. This button, when clicked, will call a function that will update our “state”, increasing by 1 the value of the counter. This change will be reflected immediately on the page. Let’s go:
class HelloComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0
}
}
render() {
var name = this.props.name;
var counter = this.state.counter;
return (
<div>
Hello, {name}. This is HelloComponent
The current counter value is: {counter}
<button>Increment</button>
</div>
);
}
}
ReactDOM.render(
<HelloComponent name={"Felipe"} />,
document.getElementById('app')
)
Ok, now we have our button. Let’s do the rest of the work. First, we create a function and we will bind it to the onClick
event of the button. Then, we will create the handleIncrement
method, which will be responsible for updating our counter
inside our state, defining its value as the current value (this.state.counter
) + 1. For this to work, we have to bind the function on the constructor, so that this
will be available to the function it is called. That way, the function can use the setState
method to update the state as we want:
class HelloComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0
}
this.handleIncrement = this.handleIncrement.bind(this);
}
handleIncrement() {
this.setState({
counter: this.state.counter + 1
})
}
render() {
var name = this.props.name;
var counter = this.state.counter;
return (
<div>
Hello, {name}. This is HelloComponent
The current counter value is: {counter}
<button onClick={this.handleIncrement} >Increment</button>
</div>
);
}
}
ReactDOM.render(
<HelloComponent name={"Felipe"} />,
document.getElementById('app')
)
Now, save everything, refresh the page, click on the button and watch as the magic happens. The counter is incremented by one at each click of the button. And, just like that, we have our React application, with a React component that has props
and “state”, and a method that updates the state when called. It is not the most useful application, but we will get there.
Summary
To summarize everything we did on this post:
- We created a basic HTML file, importing Babel, React and React DOM
- We used the “render” method of React DOM to render a paragraph on our HTML with JSX, creating our first React application :)
- We used some JSX to embed Javascript code in our template
- We divided our application in two files, one with the HTML structure and the other with the Javascript code.
- We created our first component, extending a ES6 Javascript Class. We saw what “props” are, information passed to the component, and we passed a “prop” to our component
- We learned about the “state”, which is also information, but totally managed and controlled by the component itself, and not passed to it.
The entire final code for this post can be found on the following repository: https://github.com/felipegalvao/react-first-steps
Hope this is helpful
See ya!