Fork me on GitHub
#reagent
<
2022-02-16
>
lambder18:02:53

where is the = call reagent uses to compare the components parameters before deciding it needs re-render?

lambder18:02:48

I'm thinking about extending the IFn like:

lambder18:02:51

(extend-protocol IEquiv
  IFn
  (-equiv [this other]
    (if-not (satisfies? MetaFn other)
      false
      (= (-> this meta :equiv) (-> other meta :equiv)))))

lambder18:02:21

so we can make the anonymous functions appear as not changed to the Reagent.

lambder18:02:44

but this code is not called at all

lambder18:02:04

so i wonder how Reagent circumvents the = ?

p-himik18:02:13

I believe it's this line: https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/component.cljs#L163 Don't know why your -equiv is not called though.

lambder18:02:05

you are right

lambder18:02:25

i got it in line 174

lambder18:02:55

the debugger shows the fns are compared as params

lambder18:02:15

but (prn .. in my IEquiv extensions are not called

lambder18:02:23

need to debug than one too

lambder18:02:35

yes, the debugger is not going down to my extension

p-himik18:02:00

Did you :require that extension somewhere?

lambder18:02:21

in my core namespace

p-himik18:02:52

Just wanted to make sure. Still no clue why it wouldn't get called. I'd try debugging it right in your browser - shouldn't be that hard with sourcemaps enabled.

lambder08:02:24

@U2FRKM4TW I did debug it in a browser, I see the = being called but not my extension.

p-himik08:02:57

You can step into = and see which branch is executed.

lambder09:02:07

the -equiv is called on something which is ISeqential

lambder09:02:15

possibly the param args

lambder09:02:33

which one item is the callback function

lambder09:02:45

but i don't see -equiv form my functions is called

lambder09:02:50

so to further test it I've created this:

lambder09:02:59

[:button {:on-click (fn []
                                (prn (=
                                       (with-meta
                                           (fn [place]
                                             (prn :pp))
                                           {:equiv :xonplacechanged-1})

                                       (with-meta
                                         (fn [place]
                                           (prn :pp1231))
                                         {:equiv :xonplacechanged-1})

                                       ))

                                )} ">>>>"]

lambder09:02:13

when I click it I see false printed

lambder09:02:29

and my extension:

lambder09:02:31

(extend-protocol IEquiv
  IFn
  (-equiv [this other]
    (prn :IEquiv)
    (if-not (satisfies? MetaFn other)
      false
      (= (-> this meta :equiv) (-> other meta :equiv)))))

lambder09:02:51

doesn't print :IEquiv so I guess it's not get called

lambder09:02:50

this on other hand is get called:

lambder09:02:52

(extend-protocol IEquiv
  MetaFn
  (-equiv [this other]
    (prn :IEquiv)
    (if-not (satisfies? MetaFn other)
      false
      (= (-> this meta :equiv) (-> other meta :equiv)))))

lambder09:02:56

but still returns false

lambder09:02:03

whereas this returns true

lambder09:02:05

(extend-protocol IEquiv
  MetaFn
  (-equiv [this other]
    (prn :IEquiv  other)
    (= (-> this meta :equiv) (-> other meta :equiv))))

lambder09:02:15

got it finally working

lambder09:02:24

the correct extension should be:

lambder09:02:26

(extend-protocol IEquiv
  MetaFn
  (-equiv [this other]
    (if-not (instance? MetaFn other)
      false
      (= (-> this meta :equiv) (-> other meta :equiv)))))

👍 1
wevrem20:02:15

I have a component that I can’t get to update when (I’m guessing) only the class changes. If I use strings, as below, it works as expected. But when I change over to icons (the ignored forms below) no update occurs. Even though there is a different class on the :i component, does Reagent not see it as different?

[:span.icon
 (if ((:selected @state) id)
     "YES"
     "NO"
     #_#_
     [:i.fa-lg.far.fa-circle-dot]
     [:i.fa-lg.far.fa-circle])]

p-himik20:02:17

It should. Are you sure that your DOM is not changed from having class="... fa-circle" to having class="... fa-circle-dot"? Note that the question is different from whether the icon itself is changed.

wevrem20:02:36

I’m not sure. I’m not sure I even understand your question exactly.

p-himik20:02:48

That [:i.fa-lg.far.fa-circle] should end up as <i class="fa-lg far fa-circle"> in your DOM. Find it and see if the last class changes. But that would only work if the icon library that you're using doesn't monitor for DOM changes and doesn't replace all such elements with something else. In that case, it might easily be an issue with that library. To make sure, you can simply replace those classes with some completely different classes that don't start with fa.

wevrem20:02:53

I see. Yes, it must be a library thing, because if I replace those classes with ‘x’, it works as expected. (Of course, it’s not displaying anything but inspecting the DOC I can see that the classes change as expected when I click on them). I guess it had to be something in the icon library (Font Awesome) because the test with simple strings worked.

p-himik20:02:15

FWIW, I use Font Awesome differently. It has a React package that lets you register only the used icons in your icon library and use those icons as proper React component and not some "magic" :i that get replaced with something else at some point.

wevrem20:02:06

I was just reading those docs… My current use has been following the examples in Bulma…

wevrem21:02:19

@U2FRKM4TW Thanks for pointing me in the right direction. Using FontAwesome’s bespoke react component worked.

👍 1