Over the weekend, I put together a quick app using React.js. I’ve gotta say I was really impressed. It’s the first front-end framework I’ve used that has seemed to hit the sweet spot in terms of complexity and clarity.
The app is utterly simple so I hesitate to even label this a “project”, but nonetheless it had enough complexity that it produced a couple challenges along the way. You can check it out over here.
What’s Great
-
Tooling: Holy shit! Webpack is like a breath of fresh air compared to Grunt. Part of the issue with Grunt is that every example config tries to bundle everything and the kitchen sink into the build. Webpack examples are much more modular usually targeting a specific problem. Also, since JSX necessarily is transpiled the support for Babel is first class. It took me about 3 minutes to get Babel transpiling JSX and ES6 to “standard” JavaScript, whereas I spent about 6 hours a year ago monkeying around with a Grunt config to get Babel going on an ES6 project I was working on.
-
JSX: Yeah, I know. I was a total skeptic too. I thought this was going to bring back nightmares of my PHP days but, it was just the opposite. Using JSX in JavaScript files makes the whole system feel much more like a integrated UI development environment. It reminded me a little bit of using QT on the desktop, but with a much more natural (for someone with a web background) syntax. In contrast, Angular with its pseudo-html templates or even something like Jinja on the server feel like they are imposing an arbitrary division based on file type, rather than the more natural component based division that React encourages. Finally, this allows your entire app to be JavaScript. This means fewer context changes, fewer alt-Tabs, and fewer tools.
-
Functional: React encourages you to code in a functional style, which will increase code quality by diminishing side effects. ‘Nuff said.
-
State: React removes a lot of the burden of state management that you encounter with minimal frameworks like Backbone. Instead, it uses a simple object life cycle model that automatically updates the UI when the state changes via these life cycle events. This removes the need for event mediator patterns that are common in Backbone for simple component updates, while not resorting to two-way data binding via dirty checking in something like Angular. I would say that 2/3 of my time as a front-end developer was devoted to tracking down messy state bugs when I used Backbone. I didn’t encounter one case with React where I was confused about what the state of the component was.
-
Learning Curve: The React learning curve seemed to be pretty gentle and from what I gather the framework is very extensible. This is in contrast to the cliff that must be climbed with Angular, where you have to know quite a bit to even start getting something on the screen. After climbing that cliff, I’ll admit things seem pretty magical, but quickly become annoying when the way you are thinking about how the logic of you application should be organized doesn’t follow the Angular way.
-
Reusability: Lastly, React encourages the construction of modular, reusable components. This makes sense since it was developed at Facebook, where a team might own a widget and not an entire app. In any case, it allows it to be used in cases where you only need dynamic content for one widget on an otherwise static page (or site). However, React-router makes it really easy to extend these widgets to create a full single-page web application
What’s not
- Styling: Although, I think I now like html in my JavaScript, I didn’t really like CSS in my JavaScript. Although, there is no requirement that components be styled via js, it seems to be common practice in the React community. I see a couple problems with this practice. First, it doesn’t encourage small, functional CSS classes that can be reused. Instead, it encourages you to define the complete style of a component, even if 90% of it is the same as another component. Sure you could extend the another component’s style class, but you can’t take advantage of composing a style from several classes. Second, you can’t use some common CSS hacks like defining the same property twice; not a huge deal, but I ran into it. Lastly, anything more than basic styling is still going to require the use of a real style sheet to get things like media-queries, child styling, and animations working well. Although, you can make the case that styling in JS allows the components to be fully encapsulated, note that these JS styling are inlined into the HTML. This inlining means that you can’t override the the components styling in your css without using a bunch of
!important
suffixes in you stylesheet.
Overall, this is the first front end framework, that I really enjoyed using and didn’t feel like I was battling the entire way. I’m sold (at least until Elm matures)…