← Back to home

Temporal Reagent component state

I was making a comparison today whether I should keep some temporary state of a Reagent component in a local (relative to the component) atom or in the re-frame db. Keeping it local to the component means that I can expose a more semantically-meaningful interface, but it also means that I have much less control over the component from the outside and, which is the trickiest part, I’ll have two disconnected pieces of state. There’s a fine line that I could draw between these two pieces of state, but I wonder if this line will be clear enough for the next engineer who’s going to fix bugs in my code.

Here’s how both interfaces look like:

; Keep the state in the re-frame db
  {:on-click #(dispatch [:click id])
   :on-drag-start #(dispatch [:start-dragging id])
   :on-drag-end #(dispatch [:stop-dragging id])
   :on-drag-enter #(dispatch [:enter-drop-target id])
   :on-drag-leave #(dispatch [:leave-drop-target])
   :on-drop #(dispatch [:move id])}]

; Keep some of the state in the component
  {:on-select #(dispatch [:select id])
   :on-move #(dispatch [:move id])}]

The second one requires way less glue and is obvious how to use. However it requires for the component to maintain all of the drag-n-drop information internally. The idea of having the full state of an application in a single atom is very simple to grasp and to reason about, thus powerful.

The solutions are not too different in technical terms. I think I’m going to go for the second option. I’m very tired of writing glue. Semantically-meaningful interfaces are easier to work with. And the issues will have to be fixed in any way.