Hi Torsten, Yes, that really helps, I think I understand it much better now.
What I was trying to do was to store the actual elements to be rendered in a ratom, and that was producing the undesired result I was seeing. What I believe I need to do is to just hold data in the ratom (rather than Hiccup vectors), and then use component functions to render that data. This makes a lot more sense, and your second (preferable) suggestion worked perfectly well. Thank you, Ali On Tuesday, July 25, 2017 at 8:21:03 PM UTC+5:30, Torsten Uhlmann wrote: > > Hi Ali, > > your ratom is basically a box that holds values- a map in your case. The > (main) difference between a normal atom and reagent/atom is that it will > trigger a rerender of any component that references it. That's why the > count is updated correctly (as you have noted). > > The "Add Child" method does simply add a [:div] vector to the ratom with > an already resolved @counter which is later rendered into html. Adding a > new child does not re-process the already added values but simply adds a > new one. That's why existing children do not update their counters. > > In order to change that behavior you could create a new vector of [:div] > with the current counter and replace the existing vector instead of > conj'ing to it. > > What is preferable though is that the ratom really only holds the > information necessary to render the children- in your case that might be an > int with the number of children. > > Then at the place where you now render (:children @state) you call a new > component [render-children (:children @state) (:counter @state)] that > receives the number of children and the counter and it does iterate over > them and creates a list of :div, basically the info you now have in the > ratom. > > As a side tip, when you create a list of elements in a loop you need to > add a "^key" to each element to make React happy. > > Does that help? > Torsten. > > Am Dienstag, 25. Juli 2017 10:50:33 UTC+2 schrieb outr...@gmail.com: >> >> Hello, >> >> I have the following Form-2 component which defines a local ratom called >> state. >> >> (defn main-view [] >> (let [state (r/atom {:children [:div] >> :counter 0}) >> (fn [_] >> [:div >> [:input {:type :button >> :value "Add child" >> :on-click #(swap! state update :children conj [:div >> "Current counter: " (:counter @state)])}] >> >> [:input {:type :button >> :value "Inc Counter" >> :on-click #(swap! state update :counter inc)}]] >> >> [:div "This updates correctly: " (:counter @state)])}] >> >> [:div >> (:children @state)]] >> >> ))) >> >> When I display the component, it shows the two input buttons, and a div >> with "This updates correctly: 0". >> >> Pressing "Add child" adds a new div to the :children div at the end, >> taking the current value of (:counter @state) and displaying that. So the >> first time I press the Add child button it will add "Current counter: 0". >> >> When I then press "Inc Counter", what happens is that the div which says >> "This updates correctly: 0" updates to "This updates correctly: 1". However >> the child I have added remains unchanged. If I add a new child, the new one >> will display the correct value of (:counter @state). In short, once any of >> the children are added, they never update to reflect the current value of >> (:counter @state). >> >> My understanding is that when a ratom changes, any component which >> references it will be re-rendered and hence the "This updates correctly: *" >> div updates as expected. However, any div which is dynamically added in the >> "Add child" event handler does not. Both of them reference (:counter >> @state), however only the one in the div that is created outside of the >> event handler, within the actual component function, behaves as I would >> have expected. >> >> I suspect that this is due to the way I am dynamically adding the Hiccup >> vector within the event handler, specifically that when I am dereferencing >> state I am literally just taking its value at that time rather than setting >> up the mechanism which would update the :div in the event that (:counter >> @state) is updated, as with the "This updates correctly " div. But I don't >> know for sure. >> >> Can someone please explain what exactly is happening here, and also how >> can I achieve my intended result, that of dynamically adding a new >> component which can reference a ratom and which will change when the ratom >> changes? >> >> Thank you, >> >> Ali >> > -- You received this message because you are subscribed to the Google Groups "Reagent-Project" group. To unsubscribe from this group and stop receiving emails from it, send an email to reagent-project+unsubscr...@googlegroups.com. To post to this group, send email to reagent-project@googlegroups.com. Visit this group at https://groups.google.com/group/reagent-project. For more options, visit https://groups.google.com/d/optout.