On React
React makes the front-end a fully programmable system
This is why programmers are going gaga over it. And that it takes just two and a half days to grok.
A React component is a self-contained unit that encapsulates both the view and view logic. This abstraction is fundamental to a front-end application, just like classes are to an object-oriented app, or tables to a database app.
Here is how a hierarchy of React components for an imaginary Project Management page would look like:
- ProjectPage
- StoryWall title="Current"
- Story title="I should be able to see the Project"
- StoryWall title="Backlog"
- Story title="I should be able to see the Walls"
- Story title="I should be able to see each Story"
- StoryWall title="Current"
These components map directly to both your front-end code and the actual UI, making the project highly explorable.
View as a first-class citizen
In React, the views are written in Javascript. With that kind of power, this is the kind of things you get to write:
var story = {
title: "I should be able to see the project",
isCompleted: true
};
function storyView(story) {
var title = story.title
var isCompleted = story.isCompleted ? "completed" : "pending";
return (
<div className="Story">
<h3>{title}</h3>
<span>({isCompleted})</span>
</div>
);
}
If that was crazy, then look at how easily you can render an array of stories using _.map:
var wall = {
title: "Current",
stories: [story]
}
function wallView(wall) {
var stories = wall.stories;
var title = wall.title
var storiesView = _.map(stories, storyView);
return (
<div className="StoryWall">
<h2>{title}</h2>
<div className="StoryWall-stories">
{storiesView}
</div>
</div>
);
}
Contrast this with traditional HTML based templating: they reinvent conditionals and other control structures, and the only way to reuse code is string munging through partials. Helpers and directives are high ceremony and can't be used as often as they should be. Add to that there are a whole slew of these languages that are conceptually similar but has the overhead of different syntaxes.
React makes the view layer fully programmable and thus elevates them to be first-class citizens of the codebase. This means you can can use variables and methods and control structures and all the other programming abstractions to write and refactor beautifully organized view code.
The React component syntax
The simplest React components are state-less. All they do is interpolate parameters into the view template. In this capacity it works as a functionally pure templating function, like Handlebars or Mustache.
React components are built using React.createClass({}). The API is minimal: it just needs a render method that returns a view.
Let us build Story, our first component, using the view code in the first example.
var Story = React.createClass({
render: function() {
var story = this.props.story
var title = story.title
var isCompleted = story.isCompleted ? "completed" : "pending";
return (
<div className="Story">
<h3>{title}</h3>
<span>({isCompleted})</span>
</div>
);
}
});
Once you define a component using React.createClass, you render it using React.render. The first argument to React.render is the React view that you want to render, and the second is the DOM element into which you want to mount it. Here, let us render the component:
var story = { title: "I should be able to see a Story",
isCompleted: true }
React.render(
<Story story={story} />,
document.getElementById('example1-Story')
);
And the result looks so:
Any parameter that you pass to a React component (like story in the above code) is available in the hash this.props inside the component. React considers props to be immutable, and so should you.
React and CSS - take one get one free
CSS used to be the one part of an otherwise clean codebase that first turns into a ball of mud. Turns out the trick to good CSS is to avoid cascade, the C in CSS. Cascade makes the style bleed from one unconnected part of the codebase to another, often in hard to predict ways. Modern CSS conventions - OOCSS, SMACSS, BEM etc. are all about containing this by isolating one component from the other.
However, each of these frameworks use their own terminology: BEM is about identifying reusable 'blocks', while SMACSS calls them 'modules'. But if you use React, there is nothing new to learn - you are already extracting reusable components naturally, and if your CSS adequately mirrors them, you are getting the benefits of well-factored code in your CSS for free. This is exactly what we did with our code examples: the CSS class names are the same as the component names. Naming is already hard enough; you shouldn't have to do it twice.
Any object oriented CSS framework should work well with React. I have recently started using SUIT CSS which works especially well with component-based UI frameworks. To begin with, these three conventions will take you far:
ComponentName--modifierName | eg: Notification--error |
ComponentName-descendentName | eg: StoryWall-stories |
ComponentName.is-stateOfComponent | eg: Story.is-active |
Composing components
Now let us build the StoryWall component - it is also similar to the plain view code we first wrote, except that this time we wrap it as a React component.
var StoryWall = React.createClass({
render: function() {
var wall = this.props.wall;
var stories = wall.stories;
var title = wall.title
var storiesView = _.map(stories, function (story) {
return (<Story story={story}/>);
});
return (
<div className="StoryWall">
<h2>{title}</h2>
<div className="StoryWall-stories">
{storiesView}
</div>
</div>
);
}
});
We'll render it with some data:
var currentWall = {
title: "Backlog",
stories: [
{
title: "I should be able to see a Wall",
isCompleted: true
},
{
title: "I should be able to see the Project",
isCompleted: false
}
]
}
React.render(
<StoryWall wall={currentWall} />,
document.getElementById('example2-StoryWall')
);
In action:
Here we used the Story component inside StoryWall as seamlessly as we would use a normal HTML tag. There was nothing extra to be done. This is the other aspect of React that makes it highly programmable: components are almost as fluid as functions; they are parameterized, and are easy to both compose and reuse. There are no arcane incantations to be initiated into.
What next?
React is built on simple concepts and there is very little magic going on - as soon as you understand how to do something, you also understand how it works behind the scenes. React also favors the explicit is better than implicit philosophy, even if it comes with the overhead of extra code at times. Becoming productive with the library involve just a few days of learning curve, after which you are building and reusing components with ease.
If you are a back-end developer with a bad taste for Javascript, you'll be surprised how React and a sane collections library like Underscore can make the language pleasant to use. Quoting a convert:
React completely changed the way I thought about rich clients. It took me a little longer than 2 days, I went into React with an absolute hatred of anything Javascript and came out 2 weeks later loving it. There is something to be said for a library that can wash away over 10 years of built up anger for a particular technology. It's not just another revamped library thrown into the frying pan, it's a complete rethink of how rich clients can be developed almost effortlessly with code that anyone can read. When I got into react, all I could think was "yes, this makes sense, this is how it should have been all along." Moving into the future I expect most libraries will unify under the concepts introduced by React in the same way that most web applications frameworks are different flavors of MVC.
- as response to you'll never go back to anything else
If you work with Rails, there is good news: it is far easier to get started using React in Rails than it is to setup an independant Javascript project with Gulp, watchify, reactify et al. Just drop browserify-rails and react-rails and you are good to go.
Here are a bunch of areas that you'll cover as you start using React for real-world applications:
- building stateful components and managing UI state
- explicit communication between React components using callbacks
- using the key attribute to help React differentiate between sibling elements
- component lifecycle events, so that you can use external libraries like jQuery plugins
- making use of the node.js ecosystem through npm and browserify
The official React documentation has a comprehensive tutorial that covers all these topics and more, including in-depth documentation on the working of the library itself. You should also watch Pete Hunt's excellent introduction to the React way of thinking to get a firm grip on the thinking behind React. I also recommend Ryan Florence's React Training lessons - the best resource on the web that covers real-world React use cases.
With React, becoming a front-end developer is easier than it has ever been before. You can start using it in your projects today - the component based approach means it does not need a big-bang adoption. If you have a rich widget that you'd otherwise build using jQuery and or Backbone, give React a go instead. You would be surprised at how fast you are able to write clean Javascript UI code, and how happy it makes you.