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.

Reply via email to