We’ve written a lot of React since our first React feature over three years ago when we sprinkled React into a Rail’s table view via the react-rails project. From that humble beginning we’ve moved to writing entire applications in React and even using React to render HTML on the server! To help share the knowledge we’ve learned over the years, I’ve compiled a list of tips that lead to a quality React codebase.
1. Decouple Your Code
React brings a lot to the table but at the end of the day it’s a library like any other library, rather than a cure-all. React will, if left untended, become an unorganized mess. One of the biggest lessons I’ve learned while writing React is how important it is to write “decoupled code”. Decoupling code is important because it leaves the core functionality of your application untethered to a specific technology stack or framework. This concept isn’t new or unique to React, and long-time jQuery devs will already understand this concept. But decoupling with jQuery was more difficult because the modern DOM APIs we use now were not yet available or ready back in jQuery’s heyday.
One of the best resources I’ve found about writing decoupled code comes from Jim Weirich. While his Decoupling from Rails talk uses Ruby on Rails as the example, the principles are true and apply to any software application. Jim stresses one of the key wins in decoupling from Rails is how much quicker unit tests run, and while that’s true for decoupling from React, there are other wins as well.
Benefits of Decoupling
Avoid Lock-In to a Specific Framework: Another win, which Jim also touches on, is that by decoupling from a framework your code becomes more portable. JS frameworks come and go and this usually means that at some point in an application or site’s lifetime it will get upgraded. If the core pieces of your application are framework-agnostic it makes migrating frameworks much easier and straightforward.
Easier Testing: Jim demonstrates in his talk how much quicker it is to unit-test Rails if you don’t have to spin up all of Rails to test. This applies to React as well. You don’t have to spin up Phantom (R.I.P.) or Headless Chrome just to run your unit tests. In most cases you can simply import the module or class you want to test, and test it without any other tooling.
2. Use Classnames for Dynamic Class Names
This is a short and simple tip. Use the excellent classnames package by Jed Watson to manage your dynamic classes. Instead of sprinkling ternaries all over your render methods, you can abstract those class names into variables that rely on the classnames function returning the proper name.
3. Start Simple, Stupid
The fact that most “starter projects” and tutorials include React plus a boatload of other dependencies (plugins, libraries, and other technologies that Dave lists above) is a problem. I would argue, though, that it’s not a new problem and is one that jQuery, other JS frameworks before React, and even Rails certainly have had too. Understanding what each plugin or library does and how it impacts your overall design is critical, and yet it’s so easy to add things without much thought and to end up in a mess.
4. Keep Render Clean Until It Becomes a Problem
render method can get quite messy. I usually move chunks or pieces of functionality “up and out” into class methods or plain modules to keep
render resembling a wrapper function more than a place where processing occurs. However, this can quickly make your component file huge. If you find yourself “yo-yoing” up and down a component file trying to follow the flow, it’s probably time to consolidate some of those pieces into another class method or move that functionality out into its own component.
5. Server-Side Rendering Isn’t a Silver Bullet
Server-side rendering your React application is the gold standard of the React community. Server rendering brings a couple benefits:
Potentially improved performance, since the request from the client can respond with HTML
Potential ability to reuse frontend code on the backend
Despite what you may hear, server rendering your React is not easy and it probably isn’t really possible unless you’ve already done some other things in this post. It’s best to treat the server-rendered side “branch” of your application like a completely separate platform (because it is!). Server rendering gives you another vector to decouple (and test) your application code: the DOM. To render a React component on the server, you can’t reference the DOM at all or your application will fail. Therefore you need to design your server-rendered application in such a way that it is decoupled from React and the DOM wherever possible. Server rendering is an awesome feat but it’s not something that comes without any costs in terms of time or architecture planning effort.
6. Understand How Render Actually Works
This tip applies to any framework or library: Dispel the magic. Know how the particular package works and understand its characteristics. I thought I knew everything about React’s
render method until a month or two ago when I realized via a Twitter discussion that I had incorrectly assumed something important about how React works with “foreign” DOM. This was a helpful reminder that will definitely impact how I approach future decisions involving React and third-party plugins or scripts that modify the DOM.