The Challenges of Building a Production Ready Application in the React.js Ecosystem
13 December 202104 May 2016 | Software
It’s been a full year since I started working with React on a production application. I think the time is right to share some of my thoughts about the framework and the entire React ecosystem. Do not expect to learn React by reading this post or to understand some of the concepts presented without any prior knowledge of the framework. My thoughts may prove helpful if you seek insights into the platform or need to decide if React is a good match for your project. I will focus on the parts that created problems, as most of the times these parts cause project delays and delivery problems.
Disclaimer: Working with frameworks like Angular and React was quite fun. To decide which one to choose for my projects I did quite a bit of research, which enlightened me a bit but provided too few answers to validate the choice. This is why I advise you to refrain from looking for the best framework forever. Try a few, get a feel of them and imagine yourself doing regular tasks in each framework or even do those tasks if you have the time. Ask yourself questions like: How do I solve routing with X? How do I implement a pagination mechanism with Y? How do I integrate my API into Z? These are the kinds of questions you need answered before making up your mind. Don’t follow what others (like me) are writing about frameworks.
While the setup for a new project should normally be straightforward, React has a lot of options and different tools that do basically the same stuff but with different flavors. If you are a bit familiar with React, you should also be familiar with some of these tools.
For our project we used the following tools/libraries:
- React-Router – routing and urls specification;
- Reflux.js – managing application state;
- node/npm – managing dependencies, serving the application and task runner;
- browserify – splitting the application into modules and bundling/minifying the code;
- babel.js – transpiling ES2015 code to ES5;
- isomorphic-fetch – asynchronous calls to our services;
- mocha – unit testing.
How should you decide on your project setup? I think that react-router is the de-facto choice if you need routing capabilities in your application. Babel is also the best tool available for transpiling; in case you want to write ES2015, you should use it. The others are debatable. For some tasks, ideally, you should try a few options without wasting too much time on analyzing them. Just see which one fits you and your team best and also make sure the tool you are using is popular, so you can easily find solutions to potential problems within the user community. To get the needed support we had to switch from superagent to isomorphic-fetch, for example. If you realize you made a mistake in the beginning, adjusting at some point is not a huge problem with many of these tools.
Managing the application state is a big deal when you want to scale your application. Flux is the recommended architecture that goes along with React (and takes full advantage of the framework’s good render capabilities while allowing you to scale your application without creating a bowl of spaghetti code when managing the application state; Flux can also work with Angular or other frameworks). Basically, you can start working the “flux way” immediately, without any other library in place, but sometimes it feels like you are writing a lot of boilerplate code.
When we started writing the application, flux was still pretty much in an experimental phase and a few projects that started in 2014 implemented flux with different flavors. Reflux was at that moment the most popular one and apparently the easiest one to leverage. After understanding flux, reflux seems like a great improvement because it handles a lot of complexity from your code. As our project progressed, reflux showed some of its limitations, forcing us to write some custom modules to handle some specific flows which we required and for which the framework had no support. One good example is a check we needed before each handler inside a store and which we did not want to write in each function. To solve this issue we had to write a special mix in that would do that check, then call the handler when an action is triggered and the store needs to respond.
Server side rendering
Whose best practices should I follow?
Making design decisions relying on no prior experience and very little online documentation is certainly interesting. I think everyone should try it at least once in their career. I can say I learned React and Flux the hard way, by trying, failing, trying again and so on.
There are many materials available on React today, but people still get confused when starting out. Should they use the ES2015 class syntax? Should they use the factory function examples? And what’s up with these so called pure/presentational components? The community already offers 3 or 4 ways of creating React components. Which one should they follow? I’m not saying there should be a single way of doing things, but a slightly more standardized approach to building React apps would certainly help. Just search for some starter kit solutions on GitHub and you will find a ton of different approaches. Maybe what React needs is something like John Papa’s angular styleguide, which is definitely helpful to anyone who wants to start building an app in Angular.
Managing version bumps
The major problem with the React ecosystem is that it still introduces breaking changes because of the APIs’ flexibility. The community is very active, so best practices are being defined as we speak.
We started with React 0.12 and React-Router 0.12 and today we run React 0.14 and React-Router 1.x and we plan on updating to React 15 and Router 2.x. Needless to say, we had to take some time and update our codebase, time that we will keep taking whenever necessary. This is an important part of working with a new technology; you should always be aware of the upcoming changes and make sure that your codebase does not become rigid and hard to integrate with these changes. My impression is that it will take another six to nine months before we can truly consider the React ecosystem stable.
When you do the math
Going with React was a gamble for our team, but overall I think it paid off. We have a very fast application and a very neat code base which is easily extended day by day now. We did not have such a great speed at developing the application at first, but we think we will benefit from having this setup in place for the coming functionalities. Overall, React is a good choice when you need a lot of interactivity on your website or when your entire website can be built out of small reusable components. While it is not an optimal framework for prototyping and MVPs because it adds some complexity to your system, as you application scales in both traffic and functionality you will enjoy working with it.