Péter Márton Co-Founder of RisingStack

Update: the second part is out! Learn more about the React.js way in the second part of the series: Flux Architecture with Immutable.js.

Now that the popularity of React.js is growing blazing fast and lots of interesting stuff are coming, my friends and colleagues started asking me more about how they can start with React and how they should think in the React way.



(Google search trends for React in programming category, Initial public release: v0.3.0 , May 29, 2013)

However, React is not a framework; there are concepts, libraries and principles that turn it into a fast, compact and beautiful way to program your app on the client and server side as well.

In this two-part blog series React.js tutorial I am going to explain these concepts and give a recommendation on what to use and how. We will cover ideas and technologies like:

ES6 React

virtual DOM

Component-driven development

Immutability

Top-down rendering

Rendering path and optimization

Common tools/libs for bundling, ES6, request making, debugging, routing, etc.

Isomorphic React

And yes, we will write code. I would like to make it as practical as possible.

All the snippets and post related code are available in the RisingStack GitHub repository .

This article is the first from those two. Let's jump in!

Repository:

https://github.com/risingstack/react-way-getting-started

1. Getting Started with the React.js Tutorial

If you are already familiar with React and you understand the basics, like the concept of virtual DOM and thinking in components, then this React.js tutorial is probably not for you. We will discuss intermediate topics in the upcoming parts of this series. It will be fun, I recommend you to check back later.

Is React a framework?

In a nutshell: no, it's not.

Then what the hell is it and why everybody is so keen to start using it?

React is the "View" in the application, a fast one. It also provides different ways to organize your templates and gets you think in components.

In a React application, you should break down your site, page or feature into smaller pieces of components. It means that your site will be built by the combination of different components. These components are also built on the top of other components and so on. When a problem becomes challenging, you can break it down into smaller ones and solve it there. You can also reuse it somewhere else later. Think of it like the bricks of Lego. We will discuss component-driven development more deeply in this article later.

React also has this virtual DOM thing, what makes the rendering super fast but still keeps it easily understandable and controllable at the same time. You can combine this with the idea of components and have the power of top-down rendering. We will cover this topic in the second article.

Ok I admit, I still didn't answer the question. We have components and fast rendering - but why is it a game changer? Because React is mainly a concept and a library just secondly.

There are already several libraries following these ideas - doing it faster or slower - but slightly different. Like every programming concept, React has it’s own solutions, tools and libraries turning it into an ecosystem. In this ecosystem, you have to pick your own tools and build your own ~framework. I know it sounds scary but believe me, you already know most of these tools, we will just connect them to each other and later you will be very surprised how easy it is. For example for dependencies we won't use any magic, rather Node's require and npm . For the pub-sub, we will use Node's EventEmitter and as so on.

(Facebook announced Relay their framework for React at the React.js Conf in January 2015.)

Are you excited already? Let's dig in!

The Virtual DOM concept in a nutshell

To track down model changes and apply them on the DOM (alias rendering) we have to be aware of two important things:

when data has changed, which DOM element(s) to be updated.

For the change detection (1) React uses an observer model instead of dirty checking (continuous model checking for changes). That’s why it doesn't have to calculate what is changed, it knows immediately. It reduces the calculations and make the app smoother. But the really cool idea here is how it manages the DOM manipulations:

For the DOM changing challenge (2) React builds the tree representation of the DOM in the memory and calculates which DOM element should change. DOM manipulation is heavy, and we would like to keep it at the minimum. Luckily, React tries to keep as much DOM elements untouched as possible. Given the less DOM manipulation can be calculated faster based on the object representation, the costs of the DOM changes are reduced nicely.

Since React's diffing algorithm uses the tree representation of the DOM and re-calculates all subtrees when its’ parent got modified (marked as dirty), you should be aware of your model changes, because the whole subtree will be re-rendered then.

Don't be sad, later we will optimize this behavior together. (spoiler: with shouldComponentUpdate() and ImmutableJS)



(source: React’s diffing algorithm - Christopher Chedeau)

How to render on the server too?

Given the fact, that this kind of DOM representation uses fake DOM, it's possible to render the HTML output on the server side as well (without JSDom, PhantomJS etc.). React is also smart enough to recognize that the markup is already there (from the server) and will add only the event handlers on the client side.

Interesting: React's rendered HTML markup contains data-reactid attributes, which helps React tracking DOM nodes.

Useful links, other virtual DOM libraries

Component-driven development

It was one of the most difficult parts for me to pick up when I was learning React.

In the component-driven development, you won't see the whole site in one template.

In the beginning you will probably think that it sucks. But I'm pretty sure that later you will recognize the power of thinking in smaller pieces and work with less responsibility. It makes things easier to understand, to maintain and to cover with tests.

How should I imagine it?

Check out the picture below. This is a possible component breakdown of a feature/site. Each of the bordered areas with different colors represents a single type of component. According to this, you have the following component hierarchy:

FilterableProductTable SearchBar ProductTable ProductCategoryRow ProductRow





(source: Thinking in React)

What should a component contain?

First of all it’s wise to follow the single responsibility principle and ideally, design your components to be responsible for only one thing. When you start to feel you are not doing it right anymore with your component, you should consider breaking it down into smaller ones.

Since we are talking about component hierarchy, your components will use other components as well. But let's see the code of a simple component in ES5:

var HelloComponent = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; } });

But from now on, we will use ES6. ;)

Let’s check out the same component in ES6:

class HelloComponent extends React.Component { render() { return <div>Hello {this.props.name}</div>; } }

JS, JSX

As you can see, our component is a mix of JS and HTML codes. Wait, what? HTML in my JavaScript? Yes, probably you think it's strange, but the idea here is to have everything in one place. Remember, single responsibility. It makes a component extremely flexible and reusable.

In React, it's possible to write your component in pure JS like:

render () { return React.createElement("div", null, "Hello ", this.props.name); }

But I think it's not very comfortable to write your HTML in this way. Luckily we can write it in a JSX syntax (JavaScript extension) which let us write HTML inline:

render () { return <div>Hello {this.props.name}</div>; }

What is JSX?

JSX is a XML-like syntax extension to ECMAScript. JSX and HTML syntax are similar but it’s different at some point. For example the HTML class attribute is called className in JSX. For more differences and gathering deeper knowledge check out Facebook’s HTML Tags vs. React Components guide.

Because JSX is not supported in browsers by default (maybe someday) we have to compile it to JS. I'll write about how to use JSX in the Setup section later. (by the way Babel can also transpile JSX to JS).

Useful links about JSX:

What else can we add?

Each component can have an internal state, some logic, event handlers (for example: button clicks, form input changes) and it can also have inline style. Basically everything what is needed for proper displaying.

You can see a {this.props.name} at the code snippet. It means we can pass properties to our components when we are building our component hierarchy. Like: <MyComponent name="John Doe" />

It makes the component reusable and makes it possible to pass our application state from the root component to the child components down, through the whole application, always just the necessary part of the data.

Check this simple React app snippet below:

class UserName extends React.Component { render() { return <div>name: {this.props.name}</div>; } } class User extends React.Component { render() { return <div> <h1>City: {this.props.user.city}</h1> <UserName name={this.props.user.name} /> </div>; } } var user = { name: 'John', city: 'San Francisco' }; React.render(<User user={user} />, mountNode);

Useful links for building components:

React loves ES6

ES6 is here and there is no better place for trying it out than your new shiny React project.

React wasn't born with ES6 syntax, the support came this year January, in version v0.13.0 .

However the scope of this article is not to explain ES6 deeply; we will use some features from it, like classes, arrows, consts and modules. For example, we will inherit our components from the React.Component class.

Given ES6 is supported partly by browsers, we will write our code in ES6 but transpile it to ES5 later and make it work with every modern browser even without ES6 support.

To achieve this, we will use the Babel transpiler. It has a nice compact intro about the supported ES6 features, I recommend to check it out: Learn ES6

Useful links about ES6

Bundling with Webpack and Babel

I mentioned earlier that we will involve tools you are already familiar with and build our application from the combination of those. The first tool what might be well known is the Node.js 's module system and it's package manager, npm . We will write our code in the "node style" and require everything what we need. React is available as a single npm package .

This way our component will look like this:

// would be in ES5: var React = require('react/addons'); import React from 'react/addons'; class MyComponent extends React.Component { ... } // would be in ES5: module.exports = MyComponent; export default MyComponent;

We are going to use other npm packages as well.

Most npm packages make sense on the client side as well,

for example we will use debug for debugging and superagent for composing requests.

Now we have a dependency system by Node (accurately ES6) and we have a solution for almost everything by npm . What's next? We should pick our favorite libraries for our problems and bundle them up in the client as a single codebase. To achieve this, we need a solution for making them run in the browser.

This is the point where we should pick a bundler. One of the most popular solutions today are Browserify and Webpack projects. Now we are going to use Webpack, because my experience is that Webpack is more preferred by the React community. However, I'm pretty sure that you can do the same with Browserify as well.

How does it work?

Webpack bundles our code and the required packages into the output file(s) for the browser. Since we are using JSX and ES6 which we would like to transpile to ES5 JS, we have to place the JSX and ES6 to ES5 transpiler into this flow as well. Actually, Babel can do the both for us. Let's just use that!

We can do that easily because Webpack is configuration-oriented

What do we need for this? First we need to install the necessary modules (starts with npm init if you don't have the package.json file yet).

Run the following commands in your terminal (Node.js or IO.js and npm is necessary for this step):

npm install --save-dev webpack npm install --save-dev babel npm install --save-dev babel-loader

After we created the webpack.config.js file for Webpack (It's ES5, we don't have the ES6 transpiler in the webpack configuration file):

var path = require('path'); module.exports = { entry: path.resolve(__dirname, '../src/client/scripts/client.js'), output: { path: path.resolve(__dirname, '../dist'), filename: 'bundle.js' }, module: { loaders: [ { test: /src\/.+.js$/, exclude: /node_modules/, loader: 'babel' } ] } };

If we did it right, our application starts at ./src/scripts/client/client.js and goes to the ./dist/bundle.js for the command webpack .

After that, you can just include the bundle.js script into your index.html and it should work:

<script src="bundle.js"></script>

(Hint: you can serve your site with node-static install the module with, npm install -g node-static and start with static . to serve your folder's content on the address: 127.0.0.1:8080 .)

Project setup

Now we have installed and configured Webpack and Babel properly.

As in every project, we need a project structure.

Folder structure

I prefer to follow the project structure below:

config/ app.js webpack.js (js config over json -> flexible) src/ app/ (the React app: runs on server and client too) components/ __tests__ (Jest test folder) AppRoot.jsx Cart.jsx Item.jsx index.js (just to export app) app.js client/ (only browser: attach app to DOM) styles/ scripts/ client.js index.html server/ index.js server.js .gitignore .jshintrc package.json README.md

The idea behind this structure is to separate the React app from the client and server code. Since our React app can run on both client and server side (=isomorphic app, we will dive deep into this in an upcoming blog post).

How to test my React app

When we are moving to a new technology, one of the most important questions should be testability. Without a good test coverage, you are playing with fire.

Ok, but which testing framework to use?

My experience is that testing a front end solution always works best with the test framework by the same creators. According to this I started to test my React apps with Jest. Jest is a test framework by Facebook and has many great features that I won't cover in this article.

I think it's more important to talk about the way of testing a React app. Luckily the single responsibility forces our components to do only one thing, so we should test only that thing. Pass the properties to our component, trigger the possible events and check the rendered output. Sounds easy, because it is.

For more practical example, I recommend checking out the Jest React.js tutorial.

Test JSX and ES6 files

To test our ES6 syntax and JSX files, we should transform them for Jest. Jest has a config variable where you can define a preprocessor ( scriptPreprocessor ) for that.

First we should create the preprocessor and after that pass the path to it for Jest. You can find a working example for a Babel Jest preprocessor in our repository.

Jet’s also has an example for React ES6 testing.

(The Jest config goes to the package json.)

Takeaway

In this article, we examined together why React is fast and scalable but how different its approach is. We went through how React handles the rendering and what the component-driven development is and how should you set up and organize your project. These are the very basics.

In the upcoming "The React way" articles we are going to dig deeper.

I still believe that the best way to learn a new programming approach is to start develop and write code.

That’s why I would like to ask you to write something awesome and also spend some time to check out the offical React website, especially the guides section. Excellent resource, the Facebook developers, and the React community did an awesome job with it.

Next up

If you liked this article, subscribe to our newsletter for more. The remaining part of the The React way post series are coming soon. We will cover topics like:

immutability

top-down rendering

Flux

isomorphic way (common app on client and server)

Feel free to check out the repository:

https://github.com/RisingStack/react-way-getting-started