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.