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.

2017-07-25 10:50 GMT+02:00 <outrov...@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.
>



-- 
AGYNAMIX(R). Passionate Software.
Inh. Torsten Uhlmann | Buchenweg 5 | 09380 Thalheim
Phone:     +49 3721 273445
Fax:         +49 3721 273446
Mobile:     +49 151 12412427
Web:        http://www.agynamix.de
Author of "Lift Web Applications How-To
<http://www.packtpub.com/lift-web-applications/book>"

-- 
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