This May, Viget worked with the Lupus Foundation of America to launch Know Lupus (case study) (site), a React.js-based game that teaches you about Lupus with bouncy cards and colorful illustrations. It was my first chance to work with React on a real project, so I had a blast but also learned some lessons that’ll save me time on the next project (and maybe, you too!).



Why React?

I worked with Backbone and Marionette on several other projects including DSG Running (case study) (site), and got tired of the amount of boilerplate needed to create simple elements and render them inside each other. Furthermore, Backbone’s loose model-view relationship doesn’t fit so well with highly motion-based sites — managing animation, sounds, and interface states through models can get complex quickly.

In React, making a component is as simple as typing HTML inside render() . If you want to break it up, just import smaller components and include them as <Components /> in the JSX. This is much, much smoother than managing views in Backbone, where even with the assistance of Marionette you end up defining regions by writing code in a template and transforming it to a region with an addRegions selector.

But state management is where the React + Flux architecture really shines. The state of your app is stored in a central location — at the top of the structure — and the changes trickle down through the components. You fire off Actions from anywhere in the app, and the Store listens and changes state appropriately, then broadcasts the updated state to your tree of React components. This separation seems complex at first, but in the end you write much simpler code in a place where you can easily find it, vs splitting it across several models and re-renders like you would in Backbone.

Webpack

Another important piece of Know Lupus was Webpack, another technology I was working with for the first time. Webpack is a next-level build tool like Gulp (which we've talked about before), but with a focus on connecting assets to each other via dependencies. Essentially, Webpack understands a lot more about your code than other build tools do, so it can do advanced optimizations and update code on the fly. With Webpack, I used React Hot Loader to update components and styles in real-time, trim unused code from my package automatically, and embed SVGs in my JS bundle for faster all-in-one loading.





During deploy, React-To-HTML rendered the app as static markup, and inlined my CSS into the same file. The result is a single HTML file so the intro screen actually renders on the first request. All these tricks resulted in a pretty great webpagetest.org result for a JS app.

Webpack is my build tool of choice going forward. If you haven’t, you should check out Pete Hunt’s tutorial on how to get started with it.

State

The key to getting started was to understand what states the application needed. In a simple app like Know Lupus, almost all UI state is kept together in a Store . This means that you reason about your application state — is the nav open? Has the user finished a level? What score did they get? — much earlier, and also, that you end up with a state that’s easier to understand and test. On Know Lupus, a few states in particular are especially important:

What level is a user currently on?

What state is a question in? Is it: Unasked Asked Answered, and if so: Correct Incorrect Or in the case of range answers, close enough?



With this basic data, we can derive the state of the app. For example:

If level is undefined, show the title screen.

If level is 1, and the first 4 questions are answered, show the 5th question.

If level is 2 and all questions in the level are answered, show the score screen

None of these are particularly complex states, so within a couple of hours, I had a working prototype. From that point, layering on more states like overlays and whether the nav was open or closed was pretty simple.

If you’re getting started with React, I’d encourage you to start with state — build a rough understanding of your data and how it changes before you get too deep into components. It’s tempting to let components define state, interact with each other, or talk to their parents, but most of the time you don’t need to make them do anything more than render and fire actions, so long as you have good state defined at the top of your application.

Sounds