Using React for the first time usually requires an open mind because it brings a new way of designing web and mobile applications. In fact, React tries to innovate the way we build user interfaces following a path that breaks most of the well-known best practices.
In the last two decades, we learned that the separation of concerns is important, and we used to think about it in terms of separating the logic from the templates. Our goal has always been to write the JavaScript and the HTML in different files.
Various templating solutions have been created to help developers achieve this.
The problem is that most of the time, that kind of separation is just an illusion and the truth is that the JavaScript and the HTML are tightly coupled, no matter where they live.
Let's see an example of a template:
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li><a href="{{url}}">{{name}}</a></li>
{{/link}}
{{/items}}
The preceding snippet is taken from the website of Mustache, one of the most popular templating systems.
The first row tells Mustache to loop through a collection of items. Inside the loop, there is some conditional logic to check if the #first
and the #link
properties exist, and depending on their values, a different piece of HTML is rendered. Variables are wrapped into curly braces.
If your application has only to display some variables, a templating library could represent a good solution, but when it comes to starting to work with complex data structures, things change.
In fact, templating systems and their Domain-Specific Language (DSL) offer a subset of features, and they try to provide the functionalities of a real programming language without reaching the same level of completeness.
As shown in the example, templates highly depend on the models they receive from the logic layer to display the information.
On the other hand, JavaScript interacts with the DOM elements rendered by the templates to update the UI, even if they are loaded from separate files.
The same problem applies to styles: they are defined in a different file, but they are referenced in the templates and the CSS selectors follow the structure of the markup, so it is almost impossible to change one without breaking the other, which is the definition of coupling.
That is why the classic separation of concerns ended up being more a separation of technologies, which is of course not a bad thing, but it does not solve any real problems.
React tries to move a step forward by putting the templates where they belong: next to the logic. The reason it does that is because React suggests you organize your applications by composing small bricks called components.
The framework should not tell you how to separate the concerns, because every application has its own, and only the developers should decide how to limit the boundaries of their apps.
The component-based approach drastically changes the way we write web applications, which is why the classic concept of separation of concerns is gradually being taken over by a much more modern structure.
The paradigm enforced by React is not new, and it was not invented by its creators, but React has contributed to making the concept mainstream and, most importantly, popularized it in such a way that is easier to understand for developers with different levels of expertise.
This is how the render method of a React component looks:
render() {
return (
<button style={{ color: 'red' }} onClick={this.handleClick}>
Click me!
</button>
)
}
We all agree that it looks a bit weird in the beginning, but it is just because we are not used to that kind of syntax.
As soon as we learn it and we realize how powerful it is, we understand its potential.
Using JavaScript for both logic and templating not only helps us separate our concerns in a better way, but it also gives us more power and more expressivity, which is what we need to build complex user interfaces.
That is why, even if the idea of mixing JavaScript and HTML sounds weird in the beginning, it is important to give React five minutes.
The best way to get started with a new technology is to try it in a small side project and see how it goes. In general, the right approach is to always be ready to unlearn everything and change your mindset if the long-term benefits are worth it.
There is another concept, which is pretty controversial and hard to accept, and which the engineers behind React are trying to push to the community: moving the styling logic inside the component, too.
The end goal is to encapsulate every single technology used to create our components and separate the concerns according to their domain and functionalities.
Here is an example of a style object taken from the React documentation:
var divStyle = {
color: 'white',
backgroundImage: 'url(' + imgUrl + ')',
WebkitTransition: 'all', // note the capital 'W' here
msTransition: 'all' // 'ms' is the only lowercase vendor prefix
};
ReactDOM.render(
<div style={divStyle}>Hello World!</div>,
mountNode
);
This set of solutions, where developers use JavaScript to write their styles, is known as #CSSinJS
, and we will talk about it extensively in
Chapter 7
, Make Your Components Look Beautiful.