Things nobody will tell you about React.js
The Pre Preface
Please do a mental experiment with me, imagine yourself back to 10 years ago, stop reading for 5 seconds and take a breath.
Imagine then to meet a dev from the future telling you that in 10 years anyone will be writing their app routers in Javascript in this way
and that the markup of many websites could be rendered a in this way
what would you think?
Well if that happened to me I would say: “ok so in the future we will render HTML like we do it today in our file.include.php but with Javascript right? What’s the improvement? This is not even real Javascript right? Doesn’t it throw errors?”
The Preface
I am always open to new challenges and new technologies especially if they can improve my work flow and let me grow as developer. I care about the code I write for living because:
good code means also better product quality
I really write a lot of Javascript daily and I’ve never had the chance to start coding a project with React.js since I use mainly Riot.js for my private projects and Vue.js at work. But recently I had to work on a big project with React.js and so I wanted to share my thoughts and my experience.
The Research and The First Steps
Being not an expert about how to setup a whole project with the framework (and being also skeptical about letting doing my job to a cli tool like create-react-app) I tried to understand how others scaffold their code from famous starter kits linked on the framework wiki but after digging into a couple of them I quickly understood that it was probably better doing it by myself because 61 npm modules for a basic starter kit and 104 for a more complete one were a bit too much for me.
Indeed I started by studying the way I wanted to manage my application data layer and I figured out immediately that the two biggest options were mobx and redux.
The Mobx Attempt
Mobx looked weird at the beginning because in the whole documentation they use ES2017 decorators, wich are still in an early draft release, so not yet stable, and this means I had extra babel dependencies to install (…as the whole babel setup to compile jsx templates was not enough yet…) in order to transpile them. Yes, I know I could have used mobx without decorators, but wrapping any component and any method in a mobx function didn’t seem to be a valid and maintainable solution to me.
Once I wired everything up I realized that also my eslint tests weren’t working anymore because of the decorators. I had to install babel-eslint to solve the issue. I wrote my first components but I soon realized that mobx was not really preventing unexpected updates coming from parts of my code that should not have any right to write into my stores or update them: in mobx you can prefix your store actions but “it’s just for the glam” and yet this will not prevent overriding any observable property from any component of your application!?!
In the end I understood that mobx tries to emulate wrongly what Vuex does in a much better and cleverer way for Vue.js so I uninstalled the useless node dependencies bloat and moved forward
The Redux Solution
Anytime I work with redux I need to go back to its documentation because its core concepts are so complex that my mind struggles retrieving them puking them out as soon as I stop working with it. I started implementing redux in my project, though, but after a couple of hours of refactoring I understood that my code kept growing and it was already 3 times bigger than before due to the amount of boilerplate code required by redux (ActionTypes, Actions, Reducers, connect…). At this point I decided to add some helpers to simplify at least the components’ store actions/props connections and I decided that I could live with it.
In the end I’ve found out that my app will require 3 times more Javascript code for the same trivial tasks I normally handle in Vue.js or Riot.js but it seems that React devs don’t care so I also don’t care.
The Router Nightmare
The router decision was not as hard as deciding between mobx or redux because the React.js community seems to agree mainly on react-router. React-router is not officially maintained by facebook and the maintainers had the great idea of bumping 3 major versions in 5 months completely not backward compatible so this means that all the tutorials and articles about how to use it didn’t keep up with the updates becoming useless if you are using the latest version of the library.
My initial steps with react-router were really hard because the documentation seems to be really confusing using terms like BrowserRouter
and MemoryRouter
that don’t make any sense to me, and code snippets like the ones at beginning of this article that I could barely read and understand.
Other big “mysterious” problems popped up by combining the redux Provider
component together with the Router
tag and the routes because of the React.children.only
rendering
Once I understood what was the issue I was dragged into the rabbit hole being forced to add empty divs all over the place to let my app work properly:
The Conclusion
I am sure that React was totally blast some years ago introducing new concepts that changed the way we do frontend and for this I am really grateful to the facebook devs. But today the alternatives inspired by React represent to me a much better solution for professional projects: React seems to be an enhanced rendering framework born to replace the use of server side code (probably PHP) mixed to HTML, this might work perfectly if you work for facebook but I don’t see any case where I would need it in any of my web apps.
Working with React for me raises up more problems than the ones it is supposed to solve forcing me finding out the “React way” of achieving my goals along with nosensical design decisions
- you must use
className
instead ofclass
to define the DOM css classes - you will need to import
react-dom
andreact
in your scripts without ever using the last one for some wild reason known only by the React team - you can render functional components just by using js functions but you will always need to wrap all your markup in a wrapper tag to properly allow the Virtual DOM creation
- its apparent simplicity is hidden behind a whole toolchain you need to configure before you can write even 1 line of code
I started my app with React 15.5.0 knowing that my code is deprecated before even starting because facebook has just announced that for the next major release they are planning a complete rewrite of the framework and this means that they will likely nuke the current source because it can no longer be maintained.
P.S.
Did I mention that my code will run also in a react native application?
Well, I don’t want to spoil the results of my tests and I will let you try it out first but I will give you an hint:
what do you expect from a framework with more than 1000 issues on github that will let you install alpha dependencies by default (React@16.0.0-alpha.6) to develop your native app?!?