Fork me on GitHub

@danielcompton Do you know what build tool is he using in this tutorial ? shadow-cljs, figwheel, cljsmain ?


ahh I see it's shadow 🙂


Are dynamic subscriptions recommended? As an example use-case, suppose I have an order-items element, and it takes a subscription to a list of items on the order. I want to display the current list of items, but I also want the quantities to be editable. So I have a subscription for [:order-item-quantity item-id], where item-id is a value that will be specific to each individual item, and inside my component I subscribe to as many subscriptions as there are items, like this:

(defn order-items
  [{:keys [:order-items/items-sub :order-items/base-item-sub]}]
    (for [item @items-sub :let [item-sub (conj base-item-sub (:id item))]]
      [items/item {:item/item-sub (rf/subscribe item-sub)} ,,,])])
[order-items {:order-items/items-sub some-items-sub 
              :order-items/base-item-sub [:order-item-quantity]} ,,,]


I would have a separate subscription for the collection itself so I could see items coming and going, then make the item a separate component and within the item component subscribe to individual attributes. Standard warning that I am new to re-frame myself. This might be overkill for small shopping carts, but it is a good pattern to get used to, in this case so the whole cart does not get re-rendered because one quantity changes.


As for the “too many subscriptions” concern, when it comes to reactive, as a rule more granularity is good for performance, but takes more coding. In this case I might just have subscriptions on the item list and each item as a whole.


That’s what I was thinking too, I just don’t want to build stuff like this and get bitten because there’s something in the inner workings of ratoms and reactions that I failed to understand.

đź‘Ť 4

I keep staring at your example because I know something seems off, and I think it is not so much that it runs afoul of reaction inner workings, rather I am surprised to see subscriptions as parameters. That strikes me as a potential category error. Could you instead pass some order object and then subscribe to its items and items’s attributes inside the component? ie, Work off the application entity in designing the component and just let subscriptions lay low as internal wiring?


I normally pass data and do the subscribing inside the component, I was just cheating in the example code because it let me highlight the fact that dynamic subscriptions were being created without having to write out the code for the child component.


You know what, though, your comment got me thinking about where the subscription happens, and how components interact with subscriptions, and I think you’re right: the key point is where the subscribing happens. If each child component does its own subscribing, then the scope of the subscription is the scope of the component. So basically the built-in mechanisms for instantiation and garbage collection ought to take care of any concerns related to dynamic child components. Thanks for the nudge!


It just feels a bit weird to me, like having a def down inside a function call, and I’m wondering if that’s going to create issues down the road.


Also what happens if I add new items or delete items (or delete and then re-add).