In my first post, I described the benefits of client side Javascript programming. In my second post, I highlighted some of the differences between React and other frameworks. Now It's time to get our hands dirty with React.
To follow along the example I'm going to provide, we'll use the React Starter Kit. Just click the link and download the kit.
We'll be making an example folder to hold our javascript and web
page. Go ahead and make a directory, for example example
and move
the Javascript files from the build
directory into that folder.
Next, make a simple HTML page with the following content:
<!doctype html>
<meta charset="utf-8">
<html>
<head>
<title>Hello React</title>
<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
</head>
<body>
<div id="app"></div>
<script src="./example.jsx"></script>
</body>
</html>
We'll be using example.jsx
for our code. I strongly suggest you use
a JSX aware editor such as Emacs or Vim.
Components
The core building block of React is that web applications should be built up of small, composible parts that React calls "components". For those of you familiar with GUIs, you can think of a component a bit like a widget, a single contained piece of GUI functionality. Let's dive in with a simple component that will take no arguments.
Let's say that we want to display the weather. Let's create a small component which we can use to display the current temperature. We'll call our component "Temperature", and we'll construct it using the React createClass method, which takes in an object and returns a React component.
var Temperature = React.createClass({
render: function(){
return (
<h1>The temperature is: 72F</h1>
)
}
});
We've hard coded the temperature into the component, but we'll fix that later. For now let's focus on the construction. We have created this component using the createClass method and we've given it a dictionary containing a single key, "render". The render method is what React will use when displaying our component.
When our component will render, it will display:
The temperature is: 72F
The component won't yet render on the page- for that we need to tell our component to mount to the DOM.
You may have noticed that we created a div
with the id app
in our
HTML. We will mount our component at the app
div. We didn't have to
call it app, that's just convention. We could have called it
temperature
or demo
or anything else, but app
is a good
convention to use for the top level of a React application.
To tell our React application to mount on the app
DOM element, we'll
add this to the end of our Javascript file:
React.render(
<Temperature />,
document.getElementById('app')
);
Now that we've done that, we can surf back to our web page in a web browser and we should see a plain page with our temperature prominently displayed.
Now let's replace that hard coded temperature with one we can set.
React components can have information sent to them in creation time
through the use of what are called properties. Properties are
constants which we can set at the creation time of the component and
they're stored in the component's .props
property.
Let's make that component again, but this time we'll get the temperature as a property:
var Temperature = react.createComponent({
render: function(){
return(
<p>The temperature is {this.props.fahrenheitF<p>
)
}
});
Now, where we mount our component, let's set the Fahrenheit
property. At the bottom where we mount the component, change
<Temperature />
to <Temperature Fahrenheit=80 />
.
Now save and reload the page.
You should see that the temperature is now 80.
Things are really heating up!
Now let's imagine that instead of just Fahrenheit, we wanted to take our temperature and display it for people who live outside the US, in Celsius.
We can do the temperature conversion right inside our render method!
So let's go to our render method inside our Temperature component and change it to:
var celsius = (this.props.fahrenheit - 32) * 5 / 9;
return (
<h1>The temperature is {this.props.fahrenheit}F/{celsius}C</h1>
)
If we save and go back to our page, we should see:
The temperature is 26.666666666666668C
Since that's not very pretty, we can use the built in Javascript rounding functions to make that a bit more pleasant to look at:
var celsius = (this.props.fahrenheit - 32) * 5 / 9;
celsius = celsius.toPrecision(1);
And now we should see:
The temperature is 26.6C
Much better.
At first glance, with these HTML tags and curly brackets it might look like we're using a templating system and then creating a string to pass into the DOM, but that's not what's happening here.
The HTML tags are not raw strings- they are getting pre-processed by the system and turned into function calls. These function calls are creating components, just like our components, which in turn get turned into raw DOM objects.
In addition, what's inside the curly brackets is not simply string expansion; it's fully evaluated Javascript that gets run during the render method's call.
The HTML-like syntax is called JSX, and it's use use optional but
highly recommended. You can read more about JSX at the official
documentation
but the raw javascript code is run through a pre-processor and the XML
syntax is turned into raw Javascript function calls, so a component
that looks like <foo arg={val} />
turns into something like
foo({arg=val})
. For more information on how JSX works, you can refer
to the official documentation.
Even though there is additional processing done during the pre-process phase, there's a huge runtime speed advantage of creating raw DOM objects rather than placing a string into the DOM. This translates into a faster application overall.
In addition, by using JSX, we are more able to model the output that we want, rather than worrying about the implementation of how the DOM objects are rendered to the browser, and if we use a JSX aware editor, our XML stands out from the rest of our code, making it easy to identify which parts of our code are related to rendering things on the screen.
You may have noticed that in our render method, I referred to the
Fahrenheit property as this.props.fahrenheit
while I referred to
our celsius variable simply as celsius
.
That's because the Celsius variable was set inside the render
method. The props
, on the other hand, are a property of the
Temperature class itself, and React uses the this
property to refer
to the object.
If you're familiar with Python or Ruby, this
is somewhat equivalent
to self
. In Javascript, this
will always refer to the function
that's being executed, but this
can be passed around from function
to function through binding. By default, all the methods create by
createClass have this
bound, which gives us access to the properties
of the object.
Next time
In the next post, I'll describe using state on objects, combining components and using other React component methods.