Re-frame, a Visual Explanation

Build your SPA in ClojureScript!

Master Reagent and Re-frame with my ClojureScript Frontend Signature Course.

  • 3 frontend modules
  • 72 detailed lessons
  • 19 hours of video
ClojureScript Frontend: An Eric Normand Signature Course

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:

Typical web application: User, Browser,
Server

However, there's a lot going on in the Browser. Let's explode that part out.

Web app with exploded Browser: User, HTML/DOM, Re-frame DB, Re-frame
Event Handler, Server

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.

User sees UI

She clicks the "Buy" button.

User clicks Buy

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.

:buy event dispatched

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.

temp id co-effect

Now we can have an Effect on the oustide world. Event Handlers translate Events in to Effects. We send a POST request to the server to tell it the User wants to buy.

Ajax POST effect

Meanwhile, we have another Effect, which is to modify the Database. We add the item to the cart, wherever that might be. We make sure we can reference it by the temp id later.

Database Effect

Because we've changed the cart, the :cart Subscription's value has changed. This tells the Cart View component to re-render.

:cart Subscription changes

That part of the DOM re-renders and the User is happy to see the cart now contain the tasty item 1234.

UI Re-renders

Meanwhile, that POST we did to the server has succeeded. The success handler dispatches a new Re-frame Event, this time to confirm the purchase.

POST response comes back in, dispatches :buy-confirm
event

The Event Handler gets that data and fires an Effect to adjust the database to record that it actually worked.

Database updated

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.

Structure

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.

Conclusions

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.

More posts in this Re-frame Series

Build your SPA in ClojureScript!

Master Reagent and Re-frame with my ClojureScript Frontend Signature Course.

  • 3 frontend modules
  • 72 detailed lessons
  • 19 hours of video
ClojureScript Frontend: An Eric Normand Signature Course