reagent

A minimalistic ClojureScript interface to React.js http://reagent-project.github.io/
victorb 2020-04-06T07:04:36.078900Z

@jpsoares106 you'd have to add a :display-name to your component, so the error/warning message can display it, reagent doesn't automatically add one. I haven't found a way to add :display-name without using Form-3 components, so probably you want to wrap the Form-3 component setup with a macro where you can default to putting the var name as the :display-name, if :display-name is not explicitly passed in.

juhoteperi 2020-04-06T07:06:34.079900Z

Reagent should set displayName to the name of the function: https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/component.cljs#L289, though if you use form-2 components, I'm not sure if it uses parent or inner fn name.

juhoteperi 2020-04-06T07:07:12.080200Z

(it uses the parent fn name)

victorb 2020-04-06T07:09:01.081300Z

@juhoteperi huh, I see. How sure are you about this? I haven't seen :display-name being set ever automatically I think, unless I explicitly set it in a Form-3 component, but I might very well be wrong about that and just missed it or only actually looked when doing Form-2 (not dismissing it's possible, just don't think I've seen it myself, if I remember correctly)

juhoteperi 2020-04-06T07:10:01.082Z

There are tests for this, and if you look at Reagent app using React dev tools components tree, all components use the function names

juhoteperi 2020-04-06T07:11:20.083200Z

But there could be cases where stacktraces don't contain the names. This might be affected by Reagent calling render in requestAnimationFrame or something. Or if the error is from event handler.

victorb 2020-04-06T07:12:48.084100Z

yeah, you're absolutely right, sorry about that!

juhoteperi 2020-04-06T07:14:57.085Z

https://github.com/reagent-project/reagent/issues/382 this issue looks related. Example cases where errors don't mention source fn name would be helpful, though I can probably find some cases myself.

Mario C. 2020-04-06T18:41:59.086800Z

If a reagent component re-renders does it re-render everything including child components? Or does it only re-render the parent component?

Mario C. 2020-04-06T18:45:18.088500Z

I am adding printlns in the render functions of the child components and I am noticing that they are being fired even though the inputs to the component have not changed. Could it be that the function runs but does not actually do any dom changes so in reality its not actually 're-rendering' but just running the render function?

lilactown 2020-04-06T19:22:05.091900Z

yes, it will potentially re-render all of the child components. there are three levels of optimizations happening: • reagent will do some best-effort check to see if any of your components props have changed. this will be if the arguments you pass are = to the last arguments. e.g. [my-component 1 2] will always render with the same args, so as long as it’s parent isn’t re-mounted it will not be called again. • React will do some best-effort attempt to see if the React elements returned by your component are identical?, which is usually not the case even if you’re returning the same hiccup • React will diff the VDOM elements created with what was last rendered, compute the minimal amount of changes to the page to reflect the latest UI tree

Mario C. 2020-04-06T19:39:56.092600Z

Ah, okay so if the parent component is re-mounted due to some state changes then the children will re-render again?

lilactown 2020-04-06T19:41:23.093Z

yes, if it’s re-mounted. if it’s re-rendered, it should do a check to see if the arguments are different

lilactown 2020-04-06T19:45:22.097Z

there’s another complication when a component conditionally renders some stuff. e.g.

(defn c1 []
  (let [count (r/state 0)]
    (fn []
      [:div
       [:button {:on-click #(swap! count inc)} "+"]
       [number-component count])])))

(defn c2 []
  (let [count (r/state 0)]
    (fn []
      [:div
       [:button {:on-click #(swap! count inc)} "+"]
       (if (even? count)
         [even-component count]
         [odd-component count])])))
in this case, numper-component should only mount once. each render of c1 will trigger a re-render, but if for some reason c1 changed without changing the count atom, number-component should be memoized and not be called again. c2 will re-mount evens and odds every time because the component tree changes from render to render.

Mario C. 2020-04-06T20:00:53.098300Z

So if a component that dereferences state, has the state changed like (swap! state identity) will that trigger a re-render right?

Mario C. 2020-04-06T20:01:26.098500Z

Nope it did not