A few months ago, we've decided to try the React framework in one of our projects.
As a result of that experience, I've made a presentation in our weekly "Lunch'n Learn" with the goal of introducing this new library to our team.
This blog post is a complement to that presentation. It is not a technical tutorial or a "Hello World" example:
it is rather the sharing of some thoughts that hopefully will help you to decide when and how to use this tool.
We've been used to the classic MVC (model-view-controller) pattern. Although this pattern is very useful for a clear separation between display logic and markup, it usually tends to tightly couple controllers to templates - a template can't render itself: it needs controller input. This also means that changing controllers usually implies adapting templates to those changes, and vice-versa, making maintenance harder.
As a result, templates lead to separation of technologies instead of separation concerns. In fact, both display logic and markup have the same concern: render the UI.
Take partials as an example. If we want to re-use templates, we create partials. However, by coupling a partial to the display logic, we have to make sure data is available everywhere that partial is used.
React solves these problems by combining display logic and templates into a single unit: components. Each component has its own concern, and each component knows how to render itself. Components are:
- Unit testable.
The following image shows an example of a simple UI composed by multiple React components:
A bell may ring in your head just by thinking of mixing display logic and markup. There are a few keys points to avoid creating spaghetti code:
- Keep components small;
- Only put display logic in components, avoiding data access and other code;
- Make sure each component has a single responsibility.
Handle complex UI's
We live in the era of rich user interfaces. Not only they are complex, but they also should update accordingly to lots of data changes and events, asynchronously. Implementing this behaviour is very hard:
- Need of binding changed data to UI pieces;
- Lots of UI elements;
- Lots of DOM operations;
- Lots of user inputs;
React reduces this complexity to the most simple scenario: re-render all components on each data update. This makes everything a lot easier and intuitive for developers. Instead of binding data changes to UI, React implements a one-way reactive data-flow, allowing developers to focus only on building components without worrying about UI updates. It's like we're refreshing the entire application on each data change or user interaction like we used to do in the 90's.
This is possible because React components are basically just idempotent functions: they take some parameters and output a description of the UI.
Although this is way much more simple, the truth is we are just recreating the DOM every time the application changes its state. Not only this is an expensive and slow operation, but typically it also causes flash effects, loss of scroll position, and other UI glitches, right?
The answer is no, thanks to React's implementation of virtual DOM.
High performance as default state
Virtual DOM is a technique that makes re-render extremely fast. Here's how it works:
- React builds a new virtual DOM subtree on each update;
- Diffs it with the old one;
- Computes the minimal set of DOM mutations and puts them in a queue;
- And batch executes all updates.
Since React can reason about the global state of the application at any point in time, it use heuristics to do optimisations on this algorithm. Also, React batches reads and writes for optimal DOM performance.
That said, with React we can build applications without even thinking about performance and the default state is fast.
Some considerations to take into account
In the past few years, the majority of the UI frameworks followed the classic MVC, making this the standard pattern for building web applications. We are formatted to avoid, for example, mixing display logic with markup.
React introduced a new paradigm, that contradicts these well known good practices. This means that using React can feel a little odd at the beginning, being difficult to keep confident about our code organisation. As I mentioned before, the secret here is to remember that your components must be small, contain only display logic and have a single responsibility.
Everyone in the team should be comfortable with React
One of the advantages of using MVC templates is the fact that is easier to split back-end from front-end development. For example, a developer can implement display logic while the designer creates the markup with templates, and each one is working with a separate and specific technology.
If you're using React in a project, you'll be mixing this two concepts. This means that there's not such a clear separation between technologies, and everyone will end up writing React components. So, it is important that everyone in the team invest some time to learn React so that the development flows smoothly.
Design components before coding
Before start using React in some project, spend as much as time as needed to design your application UI in the form of React components. This will force you to think of your application layout in a React way, which will have a positive impact further on the development phase.
Here's an example of a Facebook-like comment box composed by React components:
- Pete Hunt: React: Rethinking best practices -- JSConf EU 2013
- React.js Conf 2015 Keynote - Introducing React Native
- React docs - Tutorial
- React docs - Thinking in React
- Props vs State
Hit us on Twitter if you have any question. Feel free to share your React experience with us!