Flux is not a complete application architecture

Micah Condon
3 min readFeb 1, 2016

--

I highly recommend using Flux or Redux in your next application. As many of us have already discovered, building a large application without Flux can result in quite a mess. However, shoving a large application entirely into Flux stores and Action creators (or Redux reducers) can also leave you with quite a mess.

Flux isn’t your entire application, it’s just a bit of plumbing that coordinates the flow of data.

How many responsibilities does your JavaScript application have? While all applications are unique, I think there are some pretty common cases:

Remote API Access: Receive and send data via HTTP. Get my stuff.

Data Storage: Store a copy of the remote data in memory. Keep my stuff in a bucket so I don’t have to fetch it again.

Data Manipulation: Filter, sort, group, format, convert, and otherwise manipulate the raw data into structures more suitable for rendering. Organize my stuff so I can understand it, according to some business rules.

UI State Storage: Store the manipulated data in memory, along with other bits of state that make up the UI concepts. Remember which stuff I was looking at.

Render: Convert the UI state data to something the browser can draw. When the UI state data changes, update the DOM again. Make my stuff look good.

Respond to Inputs: When I interact with the DOM, change the UI state data, and possibly the underlying data, according to some business rules. Allow me to change my stuff easily.

Most of these responsibilities have very little to do with Flux (or Redux), or React. Separate these concerns to keep your code testable, reusable, and future proof.

Let’s review how Flux and React relate to each of these responsibilities.

Remote API Access: Not Flux. This code should not be inside a Flux store or action. Encapsulate your API in another class or function. Call these methods from a Flux action creator, and then feed the result into the system via another Flux action.

Data Storage: Not Flux. Your raw data doesn’t need to live in a Flux store. Keep it in a simple object or data structure. Your remote API methods can update these data objects as needed.

Data Manipulation: Not Flux. Functions for filtering, formatting, and otherwise manipulating raw data should not live in Flux stores. These can be called by Flux action creators, and the results stored in Flux stores.

UI State Storage: Flux! Use your Flux store to hold the processed data and other state that will need for rendering. This data usually comes in as a result of the data access and manipulation methods that live outside Flux.

Render: React! Take the UI state data from your Flux store and make it beautiful. Update as needed.

Respond to Inputs: React and Flux, but only a little bit. Call the Flux action creator from your React component. From the action creator, call a use case class or function that encapsulates the business rules for this interaction. Dispatch the result to your Flux store.

Write most of your application as plain old js functions and/or classes, outside of Flux. Keep them cleanly separated and well tested. Then, use Flux, Redux, or some other framework to bind them together.

Soon, I’ll share some more specific examples of how we do this in our application. In the meantime, go check out what Uncle Bob has to say on the matter. We don’t follow any of his suggestions to the letter, but our architecture is heavily influenced by these:

--

--