It’s been a full year since I started working with React. I thought it would be a good time to share some of my thoughts on the framework and on the entire React ecosystem that spawned over the last period. You are not going to learn React by reading this and you will also not understand some of the concepts without any prior knowledge of the framework. However, if you are looking for some insights or you need to decide if React is a good match for your project or not, this might help you a bit. At the end of the article I have prepared a list of links to materials that might be useful to anyone starting with React or Flux.
DISCLAIMER: While I like working with frameworks like Angular and React and I did quite a bit of research before deciding for one or another on various projects, I still advise you to not get caught in this infinite quest of finding the best framework. Try several of them, build stuff with them, see how they feel and imagine yourself (or even do it if you have the time) doing regular tasks in the context of each framework. Ask yourself, 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 kind of questions you need to ask yourself before making up your mind. Don’t follow what others (like me) are writing about frameworks.
Let’s see first where we are today with React and then I’m going to talk about how I ended up using React and the decisions I had to make. If you are already familiar with React and Flux, you can skip to the next chapter.
Flux is the recommended architecture that goes along with React (but can also work with Angular or other frameworks) and takes full advantage of the framework’s fast render capabilities. 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.
There are several great implementations and evolutions of flux today, each with their strengths and weaknesses. I will first mention reflux, because it was one of the first ones available and it changed the original flux ideas only by a bit. However, as developers realized that there are better and better ways of dealing with redundant work in flux, new implementations appeared as evolutions of flux. I will mention here redux, which slowly becomes the default choice for many new developers that start with React. Unfortunately, when I started out, redux was 3 months away from being released. Ultimately, I think redux is awesome because it encourages you to think in terms of functional programming and immutable application state, while also separating very well your view layer from your application state.
GraphQL and Relay are two technologies that want to “revolutionize” the way in which we build client applications with Relay being also considered as an evolution of flux; I’m sure that you will hear a lot about them in the near future.
How I learned to stop worrying
Back in the early days of 2015, I had to make up my mind about what framework to choose for an application that I had to rewrite from scratch. We already took the decision to implement a decoupled architecture, because we wanted to isolate a RESTful API that can be used by multiple clients. Our team previously had experience with Full Stack RubyOnRails applications and with Angular + Rails solutions. React was just emerging as a main player at that time. However, because Angular announced version 2.0 and everybody freaked out because reasons, we thought it would be a good opportunity to explore new paths and frameworks.
We narrowed them down to two and it was a decision between Ember and React. Ember seemed to have a clear advantage because it was in many ways closer to Rails; it has great integration with Rails, a powerful community behind it and a lot of active development. However we took some days to research React and we were really impressed with what the guys at Facebook were advocating for. One particular talk at the React Conf was mind-blowing:
I understand that each framework has its strengths and weaknesses, but I really liked back in the beginning of 2015 how the React team was promoting this new way of thinking about client side applications. And the truth was that I previously experienced a lot of the problems that they were mentioning as reasons for which they came up with React, starting from two-way binding hell, to highly coupled views and controllers and up to the point where you need to learn a lot of concepts that are related to one framework before jumping in and working with it. So we went for React, because it looked clean and fun. I really think that it is important, as a developer, to be able to enjoy what you are doing, even if it’s not 100% aligned with the productivity needs of your application. I’m not afraid to say that the project I started could have very well been written in Angular 1.x or maybe even as a monolithic Rails application. And maybe it would have been written faster. Going with React was a leap of faith, we had to pay a price, but in the end it was worth it.
Initially we had to cover a lot of ground and experiment fast with multiple approaches. I followed some React tutorials and I started to get used with Browserify. It felt natural and easy to use. For task automation, I just used npm tasks, because again, they felt natural and easy to use. Once I saw the power of flux, I started looking for “best practices” when it comes to the unidirectional architecture. Unfortunately, back then, it was very hard to find a lot of valuable materials, because everybody was still exploring new stuff and there were very few sources that had a strong opinion backed by practical proof.
After watching some examples and understanding the basics, I decided to try Reflux, because it seemed to address all the initial complexities of flux. After scaffolding the application and pretty much architecting with reflux from scratch with very little experience to back up my decisions, I reached to a point in which the flux flow was really great and I was able to develop a lot of components very fast and build the entire website in React. But the great part was that the code was clean, even if most of the design decisions were made on the spot with no previous model to follow.
Since the application I was building was very rich in content and needed to have the look and feel of a classic website, I immediately jumped on the router implementation of React-Router, in order to be able to simulate full urls and to work with the history API and mask the fact that the application is routing everything in the browser.
I’m going to list here some of the challenges we encountered while building our application with React.
Lack of best practices
Making design decisions with no prior experience and very little material online is certainly interesting and I think everyone should do that at least once in their career. But it is challenging nevertheless. I can say that I learned React and Flux the hard way, by trying, failing, trying again and so on. Today, we have many materials on React, but I also see a problem with the rise of ES2015. People will be confused when starting out. Should they use the ES2015 class syntax? Should they use the factory 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 that there should be a single way of doing things, but there should be a more standardized approach in building React apps. Just search for some starter kit solutions on github and you will see a ton of different approaches. Maybe what React needs is something like John Papa’s angular styleguide, which is definitely helpful for anyone who wants to start building an app in Angular. Something like this maybe? But expanded to the entire React ecosystem.
Server side rendering
Constant version bumps
We started with React 0.12 and React-Router 0.12 and today we are running React 0.14 and React-Router 1.0 (which was completely re-written). Needless to say, we had to take some time and update our codebase. This might not be a problem if you start a project today, but anyway, I thought it was worth mentioning. On top of that, we had to update browserify (6.x to 12.x!) and babel (5.0 to 6.0) which again took some time because they introduced breaking changes.
Lack of tools and plugins
Being a relatively new framework, it is often hard to find all the small plugins and extensions you need when building a modern website like datepickers, tooltips, modal windows, etc. The worst part was trying to integrate 3rd party libraries like jquery-ui (for range selectors and datepickers). You always have to write some magic code, because React doesn’t like when anyone else messes up with the DOM. So be careful how you handle this, because it might take some time to figure out how to properly integrate these 3rd parties.
I think everyone should give React a try, simply because of the different way of approaching client side architecture. Even if you continue using Backbone, Ember, Angular or any other framework, you will still learn a lot from the React ecosystem.
Food for thought
Thank you for reading this and happy coding!