Flux: Getting Past the Learning Curve
If you’re like me, you’ve probably run across the multitude of React and Flux conversations across the Internets and thought it would be a good skill to pursue. Perhaps, like me, you’ve also been able to follow along with the Thinking in React tutorial that helps you understand how to create a basic React app. Maybe you’ve even started a React app and finished some basic functionality.
Then you get about seven React components and three handlers manipulating the state, and you start to understand where Flux comes in. Your app, although small, starts to become unwieldy as you try to manage the increasing amounts of application state passing through the various React components. This must be where Flux comes in.
Where do you start? Perusing through the many Flux tutorials brings a quick realization that the next step in your application’s architecture is not so simple. This isn’t like learning another NPM package to add to your app. This is like learning MVC all over again. There are some frameworks like Reapp that could be used as a shortcut to complete your app, but it’s probably better to get a foundational understanding of what Flux is doing first. Consequently, I am writing this article to take myself step-by-step through the development of a Flux-based React application.
Starting with a Mock
Starting this process from the beginning means understanding the problem domain completely. Therefore, I’m going to start with a mock using Marvel. If you’re an advanced programmer, perhaps you can skip this step; but for me, I need to ensure I can visualize all the actions of the application before I try to conquer Flux.
After a few minutes of creative drawing on the mobile app, I ended up with the following Marvel App:
Beautiful. Now I have the visualization for some actions and views needed to complete this app. Before I get to the code, I’m going to continue my attempts to be a responsible programmer by writing down a basic outline of the app to understand the React and Flux pieces I’ll need.
To formally document what’s happening in this mock, here’s the outline:
- Click the “+” to add text for a new todo item
- Click the “+” (or hit [enter]) beside the todo item to save it
- Click the “+” to add text for a second todo item
- Click the “+” (or hit [enter]) beside the second todo item to save it
- Click the “x” beside the second todo item to remove it
Compose the Actions
A quick glance at the Flux data flow diagram suggests that I should start the Flux architecture by defining my actions. Since the outline of my app is pretty basic, this step is easy:
- NEW_ITEM add a new todo item to the list for editing
- SAVE_ITEM save the new item
- REMOVE_ITEM remove a todo item from the list
This is a good opportunity to create the TodoConstants.js file:
After I define my constants, do I jump to coding the Actions, the Stores, the Views, or the Dispatcher? In my mind, it makes sense in my mind to start with the files that have no dependencies and move out from there. This will lead me to the Dispatcher next.
When creating a dispatcher, a common convention is to create two handlers: one reacting to view triggered actions and one reacting to server triggered actions. I probably won’t have any server actions in this todo app, but I’ll add that part anyway for reference:
Now that I have my constants and dispatcher, I can use those to define the Action functions which will be used by the Views to manipulate application state. The convention for structuring the action object that gets returned is by having actionType and data properties. The composed actions for NEW_ITEM, SAVE_ITEM, and REMOVE_ITEM looks like the following:
Create the Store
The store, as the name implies, is where I keep my todo state that’s shared across multiple components. It’s also where you respond to applicable actions and change the appropriate shared state. In order to keep my todo app simple, the data will just be an array of string properties to represent todo items and an “editing” boolean field to track if a new item is in the process of being edited. With all that in mind, I searched around for a good Flux store example and found this as the basic structure:
- Require the Dispatcher, Constants, and event emitter dependencies
- Define the store as an empty array
- Define “public” event listeners and getters that views will use to listen for changes and retrieve the store (read only)
- Register the store with the dispatcher and handle each of the actions that will change the store’s data by using a switch statement and emitting a change event
Putting all of this together looks like the following:
Construct the View
Many React-Flux tutorials I encountered tackled the code for the view first. While that might be the natural process for experienced programmers, it was hard for me to wrap my head around all of the moving parts. By starting with the dependencies and scaffolding of the Flux architecture first, I now have the actions that I can use with my React components which makes more sense to me.
What’s the best way to compose the view? Well, since I already have a mock, it’s straightforward for me to use the Thinking in React approach to break down the view into components.
I’m sometimes tempted to skip this step, but it’s highly recommended to make a basic sketch for reference. The more components that are added to a project, the more difficult it is to remember the hierarchy without a visual aid.
With these components sketched out, I can now translate those directly into React components. Since I use JSX, I like to begin with a static HTML page and copy over the components starting with the inner-most elements first. For a large project, I might separate each of the components into separate files; but for simplicity, I’ll keep it all in the same Index.jsx. First, here is my starting HTML page:
When breaking these components into JSX, I realized I should probably add an EditItem component as well. This component could be dynamically added to bottom of the TodoList if the “editing” property of the state is true. In addition, I found this good flux-todomvc example that gave me many of the input text properties. The “onChange” property suggested the idea to keep the value of the edited item in the EditItem component’s state for easy access when saving the text. Finally, I searched the Bootstrap documentation and found the code for a little panel styling. In the end, these are the resulting React components:
The completed app can be found on GitHub.
Next steps? Perhaps handling the use of an API with Flux…
To cross-reference this guide with the new ES6 syntax, check out Migrating to ES6 with Babel and ESLint.
If you found this post helpful, please let me know by selecting the heart below to recommend it.