This post summarizes my tech talk at Stanford ACM on Nov 16, 2015.
React is a simple and useful library with a growing community, and we love it. But a consequence of Facebook’s hands-off approach for convention is that the community doesn’t agree on the best way to use it, especially when it comes to combining components together in a scalable way (aka architecture). There are 15+ architectures that implement Facebook’s Flux pattern, and even more that don’t. In a front-end world filled with framework FOMO, where do you start?
At Zugata, we spent a month comparing different libraries, architectures, and styles for programming in React, even forking 8 different starter kits for the initial product. We tried and nixed featureful frameworks like Reapp, inline-CSS design frameworks like Material UI, straight-up HTML5 Canvas rendering using Flipboard’s react-canvas, and more.
The criteria used to compare the stacks included the following, in order of importance:
1. The “new-engineer heuristic”
Eventually, we settled on a system that minimizes the errors a new engineer could make. Instead of making a crazy and untraceable nest of event listeners and data dependencies, we liked Flux’s approach to a unidirectional data flow, stemming from App.jsx and data stores and terminating with the simplest DOM nodes. For styling, we group LESS styles with React components, using the same name for classes as the corresponding React component and nesting small child components’ styles under their parent’s CSS class. This makes finding styles for components trivial. We also group all JSX code in various render methods (that start with the word “render”) at the bottom of each component. This eliminates the unpredictability of having angle brackets all over component code, makes CSS styling easier and quicker, eases the act of breaking off child DOM elements into separate components, and helps us create Dumb and Smart components. Speaking of which…
2. Separating Dumb components from Smart components
Explained here by Dan Abramov, Dumb components are basically very reusable components that have minimal Flux dependencies and are stateless, using only props and context. Smart components usually maintain state and respond to Flux stores and actions. To maximize code reuse and decomposition, we created a directory of “elements”, a directory of “widgets”, and a directory of “pages”. Pages are smart components that React Router maps to a route. Widgets are Smart components that aren’t mapped to routes, and they’re often reused across multiple pages and widgets. And Elements are Dumb components that are reused very frequently, use minimal CSS styles, and could easily be dropped into another React project.
3. Self-perpetuating code safety
Getting started is the hardest part. To help, I put together a starter kit that mimics our architecture and presented it during the tech talk I gave for Stanford ACM. You can use it to visualize your coworkers’ activity on Slack (screenshot below).