Fork me on GitHub
#reagent
<
2022-07-26
>
shaunlebron21:07:28

How do you guys usually store React Refs? I need to manually call a member function on one, but I’m not really sure where to put the REF. Should I attach it to this?

(defn virtual-window [props]
  (r/create-class
    {:component-did-update
     (fn [this prev-props]
       (when (not= (:size-dep props)
                   (:size-dep prev-props))
         (.resetAfterIndex REF 0)))           ;; <-- USE REF HERE

     :reagent-render
     (fn [props]
       [:> react-window/VariableSizeList
        (merge props {:ref REF})              ;; <-- GET ACCESS TO REF HERE
        ...])}))

p-himik03:07:19

Wrap (r/create-class ...) in a (let [ref (atom nil)] ...). Then you'd pass #(reset! ref %) into :ref and use it as just @ref where needed. Alternatively, you can use react/createRef instead of an atom - that's what I usually do.

🙏 2
p-himik03:07:05

But also, it's documented: https://github.com/reagent-project/reagent/blob/master/doc/FAQ/UsingRefs.md Although, that page doesn't mention react/createRef...

shaunlebron03:07:03

I don’t see any benefit to using the createRef unless they deprecate the callback method. I think I’ll use the callback, thanks!

shaunlebron03:07:14

I saw that doc page and I was just confused about how to use it with create-class, but it’s clear now that the fn is interchangeable with the create-class form

p-himik03:07:25

One benefit is that you don't have to store that callback somewhere if you want to avoid unnecessary re-renders, because functions created with the same code are never equal to each other. Another benefit is consistency - React components themselves usually use React refs. If you have to interact with such components a lot, it makes sense to use the most common mechanism.

shaunlebron03:07:25

oh wow, i didn’t realize that attaching anonymous functions to props guarantees a re-render

p-himik03:07:55

It doesn't guarantee it. A re-render won't happen if nothing changes within the component. But it some property changes and you return basically the same Hiccup with the only difference being a ref function, it will be re-rendered.

👌 1
p-himik03:07:53

At least, according to what I can recall. :) My memory can be hazy, so definitely experiment if you care about re-renders.

shaunlebron03:07:33

I don’t think I understand reagent enough. I was told to use it instead of Rum so I wouldn’t have to be explicit with how things re-render, but I’m getting snagged by not knowing exactly what is happening when I need to

shaunlebron03:07:50

I’ll try some experiments. By the way, thanks for always answering questions here. Lemme know if I can donate

p-himik03:07:49

It's certainly a journey. If you want to deepen your knowledge, I would definitely recommend learning React at least to some extent - probably everything but hooks, or almost everything, since there's not that much there anyway without delving into implementation details. Heh, thanks, I appreciate the gesture. :) But I don't have any kind of donation set up - I've got enough clientele to support my material needs.

shaunlebron03:07:50

I think I studied React enough when it came out, probably just unclear on some of the new parts. I think I’ll re-read the reagent docs again. One thing I’m unclear on is if I even have access to props inside :component-did-update inside a create-class, or if I have to use the reagent.core/props function on the this arg.

p-himik03:07:05

It's the latter, yes.

p-himik03:07:40

Here's the place where you can see how all Reagent life cycle functions are called: https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/component.cljs#L124

🙏 1
p-himik03:07:56

So basically the signature of :component-did-update is [this [this-constructor old-props] old-state snapshot]. It's very likely that you will never need this-constructor, old-state, and snapshot.

👍 1
shaunlebron04:07:57

Great! I was wondering how to get the signatures for reagent’s lifecycle function wrappers, glad to see where I can find them. Thank you

👍 1