Fork me on GitHub
Chris McCormick06:03:59

Why is it that I can use for to place elements next to each other in the dom but I can't put them in a list? e.g.

(for [x (range 3)]
  [:div x])

[:div 0]
[:div 1]
[:div 2]
but I can't do this by simply putting elements in a list. Is there any way to get elements next to each other without a wrapper element?


I am trying to do something unusual, and I'm wondering if anyone has some advice. I have a cursor c that updates pretty often - more often in practice than the component that renders it. I'd like to have a way to accumulate all updates of c , even those that are not rendered, and be able to reset them periodically - and ideally the reset would itself not trigger a render. Is there a good way to do this in reagent? I'm not sure if I can do it with a reaction - I've had little luck with reset! on the reaction. I'm also not sure if track is a good candidate - the docs and examples on these pieces of reagent are rather minimal. I also tried to make my own "atom like" thing with deftype, but I made the mistake of trying to capture updates to c using add-watch, which cannot be relied on to actually capture all updates on a cursor. Any insight anyone has would be very much appreciated!


why doesn't your component update along with your cursor?


@U4YGF4NGM I'm not sure I understand your question, but a component may render more rarely than the underlying cursor or ratom updates - otherwise, you'd risk having a UI that is lagging behind "now".


Or am I misunderstanding your question?


if your cursor/ratom updates more often then your component, wouldn't your UI be lagging behind the state of the cursor/ratom?


or are you speaking of batching?


@U4YGF4NGM This is normal in UIs - you don't necessarily process every single mouse event.


I'm not sure if there's something else you're implying, but none of it actually addresses my fundamental question, unless you're saying that there's a way to avoid events getting behind like this. In my application, there are cases where this is literally guaranteed to happen, since rendering/etc doesn't happen in the calling thread of event handlers and such.


I have cases where a user may be offline and when they reconnect, it commits a batch of changes to some underlying state atoms - and only the last one will be rendered.


(By the way, this makes sense - if you imagine my state is a checkbox, and in one update someone toggles it on and off and on again, it only matters in the end that's it is on at the end - it doesn't matter at all if it never rendered it in the off state.)


I'm probably getting hung up on a detail that may not be important to your use case, but > and be able to reset them periodically - and ideally the reset would itself not trigger a render


this seems to fly in the face of "keep your view and your state in sync" unless you're going to commit an additional change to populate the data with the next coherent state before the view is re-rendered


anyway, it sounds like what you want is a reaction-like thing that has history. reagent does not have this out of the box



(def a (r/atom {:foo 0}))

(def c (r/cursor a :foo))

;; some kind of reactive reduce that will accumulate all new values of `c` into a vector
(def c-history (reduce-reaction conj [] c)) 


since you want to be able to control the reaction from the outside (i.e. reset it in a way that isn't tied to c) you can't use a reagent reaction, since they're read only


you're probably on the right track creating your own type. you'll need to copy the implementation of make-reaction and the Reaction type to ensure reactivity and cleanup happens right


it's pretty complex, but doable


perhaps there's an easier way


I just open sourced an experiment I did awhile ago that is very similar to this.


it might serve as a jumping off point. hope it helps!


@U4YGF4NGM Thanks a lot for taking so much time to respond. I'll take a look at the project you linked!