I’ve been using Reflux for the past while now and up until recently, whenever I needed to make an API call, the workflow has been my React component triggering the action, the action emitting to the store and the store making an AJAX call and storing the result. Simple right?
It turns out that this isn’t the best pratice for a couple of reasons:
Stores are simply means of storing data. The dumber they are, the better
The action of asking for data should be be moved into it's own utility to better seperate concerns
If the AJAX call doesn't return the response your store expects, you can choose to not even acknowledge it in the store.
Keeping this in mind, let’s redesign the way we make AJAX calls in Reflux.js!
Here we have a simple React component that triggers a PostActions.loadPosts before it mounts.
And here’s our actions that handle that loadPosts
So basically what’s happening here is when we make our createActions an object, we can assign a key to it called children, this has an array containing either completed, failed and also progressed (but we won’t use progressed in this example).
The completed and failed actions are then reflected in the store by attaching either suffixes onto the corresponding function’s name in the store.
Now that we understand the general workflow, let’s hook up our API Util classes!
We need to create a class that acts as a wrapper for all our API calls. It may be very tempting to just fall back to using jQuery’s $.ajax (which is awesome, I’m not knocking it one bit), but if that’s all we’re using jQuery for, then there’s no need to include the entire dependency in our project. It’d be much easier to write our own AJAX wrapper, which would look something like this:
Now that we have our API Util, let’s hook it up to our actions.
And we just handle the outcome in our store with onLoadPostsCompleted and onLoadPostsFailed and we should be good!
That’s the basic idea behind the workflow. The component will trigger an action, the action will call an API Util call that makes the API call and returns a promise, the action listens to that promise and calls either completed or failed based on the outcome of the promise, the store then has two seperate functions that respond to both the completed and failed events emitted by the action.