Re-frame, a Visual Explanation
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
Building an app is already a complex business. You want your framework to reign in that complexity largely by organizing it into a structure. There are a lot of parts to Re-frame. I call them building blocks. It's easy to get lost and overwhelmed by the sheer number. But Re-frame is definitely putting a much simpler structure over the messiness of apps. One way to see this is to draw a sequence diagram.
A typical web application looks like this:
However, there's a lot going on in the Browser. Let's explode that part out.
Re-frame uses Reagent and hence React to manage the DOM. You still have to learn it, but it's a really solid abstraction that we won't need to expand out either mentally or visually. I'm going to expand out the Database and the Event Handler because they play big roles.
Let's step through a scenario.
First, the DOM is rendered on the screen, photons leave the screen, and impinge on the User's retina. She likes what she sees.
She clicks the "Buy" button.
The click handler on the button dispatches a
Re-frame Event. It's called
:buy and has the item id
bundled with it. That event is grabbed by the Re-frame Event Handler.
We want to do "optimistic update", which means we tell the user that the operation completed before it has been confirmed on the server. To do that, we want to get a unique id to tag the item in the cart. When the response comes back from the server, we'll be able to find it again.
We want to keep our Event Handler pure, so we use a Re-frame Co-effect to generate a temporary id for us. Co-effect is a difficult name, but the idea is easy. It's just the impure data your handler needs to run.
Because we've changed the cart, the
:cart Subscription's value has
changed. This tells the Cart View component to re-render.
That part of the DOM re-renders and the User is happy to see the cart now contain the tasty item 1234.
POST we did to the server has succeeded. The success
handler dispatches a new Re-frame Event, this time to confirm the
Now, because the Subscription's value doesn't change. The same items are in the cart so nothing new or modified needs to be rendered. We're done and the User doesn't know the difference.
Take a look at the Event Handler line on the last image. All of the arrows leaving the Event Handler line are Effects. All of the arrows entering the Event Handler line are Events (except for the Co-effect which is specified in the Event Handler itself).
There's only one line leaving the HTML/DOM line to the right, but they should all be Events. And lines come back to the HTML/DOM line as Subscriptions. Lines come to the Database as DB Effects and leave as Subscriptions. There really is a very simple structure if we look at it this way.
There are quite a number of things to learn in Re-frame. However, they all serve a specific purpose in the service of your application. I believe this squence diagram approach has shown that there is a way to organize these parts so that they don't seem quite so numerous and superfluous.
In fact, I believe this sequence diagram could be a valuable tool for designing how your app is structured. It can help you figure out what Events you need, how to handle communication with the server, and how they fit together.