Fork me on GitHub
#reagent
<
2017-10-05
>
rnagpal16:10:54

I added console statements in various methods of component

rnagpal16:10:10

I see the render console statement called first

rnagpal16:10:18

and then the component did mount

rnagpal16:10:08

and I dont see the component will receive props called after

rnagpal16:10:29

but the component is rendered with new re-frame subscription data

pesterhazy16:10:35

@rnagpal that's not enough information to go on

rnagpal16:10:49

What more information should I add @pesterhazy

pesterhazy16:10:19

why do you assume that component-will-receive-props will be called?

pesterhazy16:10:30

do you actually change the props?

rnagpal16:10:22

Here is the code

(fn [opts]
  (let [data-sub (re-frame/subscribe [::data-sub])
        show-loading? (reagent/atom false)]
    (reagent/create-class
      {:display-name "generic-loading-component"
       :component-did-mount
       (fn component-did-mount [_]
         (js/console.log "In component-did-mount of loading")
         (when-not @show-loading?
           (js/setTimeout #(when-not @node-events
                             (reset! show-loading? true))
                          100)))
       :component-will-receive-props
       (fn component-will-receive-props [_]
         (js/console.log "In component-will-receive-props of loading")
         (when @node-events
           (js/console.log "reset show loading to false")
           (reset! show-loading? false)))

       :component-will-update
       (fn component-will-update [_]
         (js/console.log "In component-will-update of loading")
         (when @node-events (js/console.log "reset show loading to false")
                            (reset! show-loading? false)))

       :reagent-render
       (fn [opts]
         (js/console.log "In Render of loading")
         (if @show-loading? [:div "LOADING"]
                            [show-data @data-sub opts]))})))

pesterhazy16:10:39

yeah looks like you're not actually changing the props, opts

pesterhazy16:10:06

for background, there are three ways to cause a component to rerender in React

pesterhazy16:10:30

1. this.state 2. this.props 3. manually calling render on the component again

pesterhazy16:10:51

Reagent typicaly doesn't use 1; 2 is pretty obvious

rnagpal16:10:09

So in case of subscription does the react lifecycle not come into picture ?

pesterhazy16:10:10

If you change a ratom, reagent does 3

pesterhazy16:10:59

yes it's still a lifecycle change, but comoponent-will-receive-props won't be called

pesterhazy16:10:14

component-will-update should be called though

pesterhazy16:10:42

one trick is to use an outer comp/inner comp pattern

pesterhazy16:10:00

you'd pass the changes to the inner component, which then gets an explicit prop change

pesterhazy16:10:42

another option is to inspect your ratom in component-will-update

pesterhazy16:10:57

depends on what you want to achieve really

rnagpal16:10:12

@pesterhazy can you please point me to the source code that is responsible for updating the component based on subscription

rnagpal16:10:30

I would want to understand how exactly the component will behave

rnagpal16:10:40

if subscription data changes

rnagpal16:10:17

Just like you mentioned component-will-update should be called though

rnagpal16:10:22

you are right

pesterhazy16:10:41

it's a batch/queue-render call wrapped in a Reaction

pesterhazy17:10:36

this enqueues the component to be re-rendered at a later point, e.g. at the next tick

rnagpal17:10:36

Thanks a lot @pesterhazy. Going through the code now

pesterhazy17:10:30

it's a bit cryptic 🙂