For better or worse, we're about to embark on creating a set of cascading dropdowns with Flux and React. This is part 1. I'm hoping/planning to release the code in a part 2. If you want a good example of some of the code bits, check out Jonathan Creamer's post on Flux. He gave me some great insights to the flux+react architecture.
I would argue that maybe Flux and React is overkill for this project. Time will tell though. There are definitely other ways to accomplish this task.
Let's start with React. React is an interesting choice for this project because there are going to be a lot of DOM elements changing. React shines at this, as it chooses the most efficient way to rewrite the DOM where necessary.
Each of my react components on the front end (the dropdowns themselves) will know nothing about what they're doing. They won't even know the type of data that they will receive. This is where React + Flux play well together.
A preview of the architecture:
The beauty (some would call it verbosity) of flux is in its attempt to decouple everything. To a fault. But in some ways it's nice. For my cascading dropdowns, I want flux to manage the flow of data so that my UI doesn't have to worry about it.
Here's the basic flow (as you may have read already). I'm going to start with the store.
Stores are Flux's way of maintaining state outside of a view. Views register listeners on a store. When store data changes, the store emits a change message. View hears it, triggers a re-render, and the view changes. How does it change? Here's the magic. Right before it re-renders, the listener on the store change actually calls back to the store and says "give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore." Basically the store gives the state to the View.
"give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore."
The view takes this state (already sanitized so all keys are named the same) and re-renders what's necessary in the UI. The great part of react is that if you set your master view to be listening to the store, the changes just drip down to all the dependent components.
Now for the good part. The view has one little
onChange method on the
<select> item which triggers an action. Hold on to your seatbelts.
The arm we'll add to the flux flow is a utility to grab our data, know how to process it, and send it back. Remember, we're all client side at this point. This extra arm we add will be our communication portal to the dark side.
The action will send data to our main application logic, and then it will go to sleep and dream of other things.
API Utility / Application Logic
Warning, this is not part of the flux flow. This is a file that (for this project specifically) knows the logic of handling things like dependencies for the cascading properties of our app. It will receive the data from the action, figure out which API calls to make next, make them, and then send the new data back to...guess who? Another action! This action will take the data, label it as a Server action (just for fun...since we got the data from the server), and send it to (drumroll please...) THE DISPATCHER.
All that fanfare for a very straightforward piece of the flux puzzle. The dispatcher is mostly self-explanatory. Except for one thing. It doesn't act like a traditional pub-sub system. It dispatches its payloads to ALL of its callers. Its callers are the Stores. Each store will determine which payloads it cares about and handle them accordingly. There are also some fancy things like
waitFor that don't apply to this project, but I'm sure make things even easier.
So that's...kind of the whole flow. Once you wrap your head around the ideas, the flow can be quite straightforward. It gets messy to me when I'm trying to figure out who should talk to my application logic and who should know about state (I've determined that only the store should know about state).
The great part about React is that you can integrate it into the view layer of your app without too much trouble (ok, a little).
The great part about the Flux way of doing things is that it requires almost no dependencies, just some conventions to follow. According to the developers who created it, its goal was to let them keep a simple mental model while developing. I quite like the idea.
My complaints? Seems quite intricate, even thought de-coupled. Quite a few files. Quite a ramp-up time for somebody brand new to the ideas.
But once you get the concepts, it's quite fun to do. It takes two-way communication and binding out of your mind. You end up creating a giant loop of communication, but in some ways it feels cleaner. Time will tell.
Stay tuned for part 2 where I dive into how this thing is actually coded.
And please let me know if I've missed anything here. I've only been exploring the flux + react world for a couple of weeks. I'm sure I'm missing some good bits.