-
-
Notifications
You must be signed in to change notification settings - Fork 715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Most Efficient Design Layouts? #304
Comments
Generally speaking, using subscriptions for more 'exact' data will be more performant (so the latter example in your case) and usually it encapsulates your filtering logic better. Your render function would run whenever |
Join clojurians via: http://clojurians.net/ Yes, as @thenonameguy says, the first variation will rerender each item every time there is a change to the all-items collection. That's probably inefficient if only one of them has changed. You will need something which renders the entire list: (defn items-list
[]
(let [items @(subscribe [:all-items])]
[:div
(for [i items]
(let [id (:id i)]
^{:key id} [item-renderer id]))])) This renderer will rerun each time there is a change to the items collection. But we oganise for it to do as little rendering as possible. And all items have a Then we need to write the (defn item-renderer
[id]
(let [item @(subscribe [:item id])] ;; obtain the individual item
[:div (:name item)])) This assumes there are two susbcriptions:
Of course, there are variations on this. You could pass in the entire item to the item render, rather thsan the id. And then the item renderer doesn't have to source it again internally. But that will means Reagent has to do equality checks on each item, on each render. Which is not a bad strategy if the list is fairly stable, but if items are getting added and removed near the top, that probably sucks. |
Personally I found it handy to have both an ordered collection (i.e. a vector) and keyed one (i.e. a map). On the other hand, having the same "object map" in two places is cumbersome because you suddenly need to do updates in two places. Thus I use the following pattern quite often: (def default-db
{:items [3 42 1]
:by-id/items {3 {:id 3
:name "Foo"}
42 {:id 42
:name "Bar"}
1 {:id 1
:name "Baz"}}})
(reg-sub
:item-ids
(fn [db _]
(:items db)))
;; can be made marginally more effective by using :by-id/items
;; subscription instead of the full DB (does it? Would love comments
;; by the team!)
(reg-sub
:item
(fn [db [_ id]]
(get-in db [:by-id/items id])))
;; in case you need a "joined" subscription, too
(reg-sub
:by-id/items
(fn [db _]
(:by-id/items db)))
(reg-sub
:items
:<- [:item-ids]
:<- [:by-id/items]
(fn [[item-ids items-by-id] _]
(mapv items-by-id item-ids)))
(defn item [id]
(let [item @(subscribe [:item id])]
[:li (:name item)]))
(defn items-list []
(let [item-ids @(subscribe [:item-ids])]
[:ul
(for [id item-ids]
^{:key id} [item id])])) This particular snippet is completely untested, but I hope you get the idea. |
@si14 yeah, nice approach. |
@si14 if ever you wanted to put together a PR for a docs page (in repo's /docs) on this, or a blog post, I'd like to link to it. I have a feeling this is practically an FAQ. |
@si14 Suppose you have multiple |
As far as I can tell, I'm okay to close this issue. |
For those who are interested, a link to the mentioned subgraph library. |
Libraries are listed in an FAQ: If anyone creates new a solutions, can you supply a PR updating that FAQ document please. |
Hello!
I've got a project with a large number of elements in a hash.
And reagent renders a list from them.
Wondering what is more efficient -- to make a number of dynamic subscriptions or have one subscription and pull the data from it in the view?
Or something like this:
Any general thoughts? I am keeping the amount of stuff passed into the components smallish - ids and things. Just wondered if there was a substantial gain using either approach. I go back and forth though in my head - because dynamic subscribers seem to need to be created / destroyed / updated / cached, while "get" just pulls out of a hash. On updates I'm guessing there is a great benefit.
And if this is in the docs, please pardon me - the docs have recently changed quite a bit!
Additionally, i was unable to find a way to join the re-frame slack channel (it must be some type of common knowledge that I'm unaware of) - so maybe this question would be better asked there?
Thanks!
The text was updated successfully, but these errors were encountered: