How we chose React
In a recent project to build a comments widget, we decided to experiment with different approaches and frameworks. This post explains what we did and how we ended up choosing React.
What we didn’t want
beforeEach of every set of tests. Overall it felt like we had to warp our brains into Angular’s world, rather than the framework helping us and then getting out of the way.
Our code had lots of verbose DOM manipulation that made it hard to read. And we were having a lot of trouble with state. When your frontend code consists of step by step manipulation of the DOM, the state of your program is stored partly in the DOM. For example, if you show nested comments by removing a hide class, the state of your system has changed. But because that state is stored implicitly in the DOM, rather than explicitly in a data structure in your code, it’s easy to write code that assumes the DOM is in one state when it is in a different state. This leads to confusing bugs.
Ideally, we wanted to have code for turning a data structure into an HTML component separated from the code that created and manipulated that data structure. This sounds like we wanted a templating library, so we ignored our previous bad experience with Angular’s templating and tried Rivets, which is similar to Angular’s templates.
We started to rewrite our widget using Rivets. But we quickly realised it wasn’t the right choice: it isn’t well maintained, its documentation is poor, and like Angular’s templates, it gives errors that are hard to debug.
So we had to think deeper about what we wanted.
React and Riot
To compare them, we spent a morning with one person writing the widget in Riot and the other in React. Then we swapped in the afternoon.
As we were rewriting the app in React, we found it a pleasure to use. For example, we had a photo uploading component within the widget which had to be displayed in different states depending on whether there were no photos or some photos, whether the photo upload limit had been reached or not, and whether a photo was currently being uploaded or not. We decided to create objects that defined each photo uploader state and then re-render the component every time the state changed. Rewriting the component this way was easy despite the multiple state changes going on. This shows the power of programming state change explicitly and separating logic code from templating code.
What we learned
The most important thing we learned was about how to deal with problems: If you’re having problems with your current approach, stop and solve the problem. Don’t just plough on thinking that going back will take too much time. It will take you more time fighting with a solution that doesn’t work properly and will lead to a worse result.
We also learned more about how to design front-end apps. We found that manipulating data and then re-rendering a stateless component based on that data is far easier to reason about than doing imperative DOM manipulations. From the comparison between Angular and React we learned that a library of few simple composable entities like functions or components are much easier to use than a framework with many overlapping and hard-to-understand concepts.