If I understand this correctly, you're actually passing in a om/build'ed 
component as a part of a cursor to another component? I'm not sure whether this 
is the cause but I think this is very likely bad form.

If you want to do something like that I would suggest you passed in the cursor 
for the subcomponent that you wish to build, and a fn to build the component as 
an opt. Note, you shouldn't pass in anything via opts that should cause a 
rerender when changed, so this would preclude creating a closure over data 
(your cursor) and passing it via the opts. I would probably move all of the 
cursor building out of :fn and make it happen in the multimethod, passing the 
result to filter-header, along with bound-tree fn as an opt.

Then filter-header will call build on bound-tree with the data you passed in. 

That's all assuming you can't refactor it to avoid this. I've generally only 
used this pattern if I want to wrap components with a generic component (e.g. a 
drag drop component). 

Lucas



> On 4 Dec 2014, at 20:29, Colin Yates <[email protected]> wrote:
> 
> I have isolated the code in question and it was written very early on (e.g. 
> woooh, here be dragons :)):
> 
> Essentially I have a component which calls a multimethod to render a child. 
> This is the implementation of that multimethod. This itself uses a common 
> component and passes in components to that common component.
> 
> Adding a key to the returned component (that isn't a keyword but a string(!)) 
> gives React enough help so it doesn't unmount it. 
> 
> For clarity, filter-header simply displays a nice formatted title and puts 
> "main-component" into the body.
> 
> [code]
> (defmethod layout/render-right-component ::consultant
>  [{:keys [owner data]}]
>  (om/build
>    c/filter-header
>    {:id :consultants
>     :main-component
>     (om/build
>       tree/bound-tree
>       nil
>       {:fn (fn [_] {:nodes (om/observe owner (state/all-consultants))
>                     :selected-ids (-> data :filter :consultants :selected-ids)
>                     :expanded-ids (-> data :filter :consultants :expanded-ids)
>                     :local-search (-> data :filter :consultants 
> :local-search)})
>        :opts      {:change-fn
>                    #(search data true)
>                    }})
>     }
>    ;; WITH THIS REACT NO LONGER UNMOUNTS
>    {:react-key "Consultants"})
>  )
> [/code]
> 
> As to the reduced problem, I need to keep poking, and I still don't 
> understand why it needs the "Consultants" key...
> 
> This realising components in state (e.g. the :main-component) isn't doing it 
> for me so I think I might utilise more multi-methods. The problem is always 
> how to deliver the focused cursor into the defmethod (e.g. 
> render-right-component really wants to take in the cursor at (:filter 
> :consultants). But that is another experiment.
> 
> Any advice is welcome.
> 
> On Thursday, 4 December 2014 12:13:16 UTC, Lucas Bradstreet  wrote:
>>> On 4 Dec 2014, at 20:02, Colin Yates <[email protected]> wrote:
>>> 
>>> Hi Lucas, thanks for the info.
>>> 
>>> You are right - I should have been clearer. My scenario is that the 
>>> component hierarchy itself isn't changing only the app-state that the 
>>> hierarchy is mapped to.
>>> 
>>> In its simplest form, think of a combo-box. The app-state is {:text "" 
>>> :results []}. The component has an input field mapped to :text and a <ol> 
>>> mapped to :results. Changing :text populates :results accordingly.
>>> 
>>> Your point about keys is worth investigating. Where I am setting keys 
>>> (mainly on dynamic children) they aren't changing. I'm not setting them 
>>> elsewhere though, which might be worth a look.
>> 
>> Hmm. Maybe the lack of keys on some components may be the issue. Perhaps 
>> react can't assume that the components are the same and thus unmounts and 
>> remounts them (the dom diffing ensures this is still fast) e.g imagine an 
>> unordered list where a list item is inserted mid list. I haven't tested 
>> whether this is true. 
>> 
>>> 
>>> Another clarity question - if an ancestor component is remounted does that 
>>> cause all children to be remounted? It might be something much higher up in 
>>> the hierarchy causing a remount...
>> 
>> I would think so. Again, I haven't tested this. 
>> 
>>> Thanks for confirming my assumptions anyway, I will dig in a bit deeper.
>> 
>> Please let us know the result. 
>> 
>> Cheers
>>> 
>>>> On Thursday, 4 December 2014 11:39:44 UTC, Lucas Bradstreet  wrote:
>>>> Hi,
>>>> 
>>>> Changes to app state *can* cause components to be unmounted. Imagine a 
>>>> component that renders another component, if a boolean value in the app 
>>>> state is true, otherwise it renders and empty div. When the boolean 
>>>> changes from true to false and the component is re-rendered, the 
>>>> subcomponent will be unmounted. 
>>>> 
>>>> However, if the subcomponent should be re-rendered in both cases, it 
>>>> should not be unmounted. 
>>>> 
>>>> Thinking about it, you're probably mistakenly using a different react-key 
>>>> between the renders. This will cause a new component to be mounted as it 
>>>> is not treated as a continuation of the previous component. 
>>>> 
>>>> Lucas
>>>> 
>>>> 
>>>>> On 4 Dec 2014, at 19:29, Colin Yates <[email protected]> wrote:
>>>>> 
>>>>> Hi all,
>>>>> 
>>>>> I am seeing a component consistently unmount/remount every time the 
>>>>> application state changes. If I change the local state instead then it 
>>>>> doesn't umount but simply re-renders as I expected.
>>>>> 
>>>>> I didn't expect changes in app-state to cause an unmount/remount only a 
>>>>> re-render (as that is my understanding of React's lifecycle). Further, 
>>>>> since I am talking about this my assumption (and the behaviour I am 
>>>>> seeing) is that om will only call the render protocol method if the 
>>>>> values have actually changed.
>>>>> 
>>>>> If my assumptions are correct I will see if I can reduce the problem into 
>>>>> a simple gist.
>>>>> 
>>>>> The reason this is a pain, performance aside, is because a re-mount loses 
>>>>> focus and this specific component is a text field. I notice in the 
>>>>> discussion on text-fields in the Basic tutorial "text" is component 
>>>>> local, maybe now I understand why as this seemed to me to go against the 
>>>>> grain of what is advised to go into local state...
>>>>> 
>>>>> Can somebody please clarify?
>>>>> 
>>>>> Thanks!
>>>>> 
>>>>> -- 
>>>>> Note that posts from new members are moderated - please be patient with 
>>>>> your first post.
>>>>> --- 
>>>>> You received this message because you are subscribed to the Google Groups 
>>>>> "ClojureScript" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>>>> email to [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> Visit this group at http://groups.google.com/group/clojurescript.
>>> 
>>> -- 
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> --- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "ClojureScript" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at http://groups.google.com/group/clojurescript.
> 
> -- 
> Note that posts from new members are moderated - please be patient with your 
> first post.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "ClojureScript" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to