Fork me on GitHub
#reagent
<
2018-02-03
>
caleb.macdonaldblack02:02:02

Any idea why custom attributes are not working for me? [:div {:myattr "1"}]

justinlee02:02:36

@caleb.macdonaldblack I believe that react drops any unknown attributes. if you need to use them, prefix them with data-

justinlee02:02:32

I think with with react 16 it will let you do it

caleb.macdonaldblack02:02:42

@lee.justin.m Ahh okay. I’m using http://barecss.com/ which has a col attribute. I will use something else I think

justinlee02:02:12

^ yea that’s what I remembered. pre-16 it drops unknown attributes

joshkh07:02:14

@lee.justin.m yup, i was puzzled too. i guess if i wanted to store a reference to each of a component's direct children dom nodes then i'd have to do something like the following, but it only gives me a ref to the parent container and then i have to use js dom selectors / jquery to find the children. (i'm being stupidly pedantic about this. 🙃)

(defn ul-list []
  (let [refs (r/atom nil)]
    (r/create-class
      {:reagent-render
       (fn []
         (into [:div {:ref (fn [e] (reset! refs e))}]
               (r/children (r/current-component))))})))

joshkh07:02:38

also, if i wanted to pass the refs value to each child, i have to pass the atom itself and let each child to the dereferencing, otherwise the component will get stuck in a render loop

kurt-o-sys10:02:35

I know it has been asked before (including by me 🙂 ) but I hope there's an more elegant way now: how to use existing react components in reagent? I'd like to use https://github.com/apollographql/apollo-client in one of my projects, but as usual, when I'm trying to use existing react components, I get stuck. So, how to this component into a reagent (or re-frame) project? This basically comes down to: how to translate this into cljs:

import ApolloClient from 'apollo-client-preset';
const client = new ApolloClient();

mikethompson10:02:53

I'd imagine use would go like this:

(def apollo  (reagent/adapt-react-class js/ApolloClient ))

then use it in hccup, like this ... 

[apollo   ......] 

mikethompson10:02:20

Or perhaps use the :> shortcut

[:> js/ApolloClient  ...]

kurt-o-sys11:02:15

ok, thx. will try

gklijs11:02:49

@kurt-o-sys you might want to take a look at https://github.com/oliyh/re-graph haven't used it myself yet, but you should be able to use it without needing re-frame.

kurt-o-sys11:02:24

yeah, I saw that. I am using re-frame, so it may be interesting. I'm not sure if it has the same features of apollo, though, like caching. Or if authorization on subscriptions/ws will work out fine.

joshkh11:02:37

i know i've seen that shortcut before but can't find it anywhere in the docs. what does it do again?

kurt-o-sys11:02:34

re-graph? it basically connects to graphQL back ends.

joshkh11:02:06

oops, i meant :>

kurt-o-sys11:02:15

oh 🙂 - lol. I guess it imports and loads existing react modules (not sure though)

joshkh11:02:40

ha, googling :> is futile

justinlee20:02:14

@joshkh i think that’s right. i’ve never used that technique you used with into--I think you are just wrapping each child in a div so you have access to the ref (?). pretty neat idea. in JS I would have just passed a callback to each child that mutated the this.refs map, but i think anything will work.

joshkh20:02:46

@lee.justin.m if you want a working example for funsies, this is how i'm getting properties of the children components (which i'll later use to set some transitions). for once i'm approaching the line where the safety of immutability vs the ease of mutability collide.

(defn obj->clj [js-obj]
  (into {} (map (fn [k] [(keyword k) (oget+ js-obj k)]) (js-keys js-obj))))

(defn get-bounding-client-rect [dom-node]
  (ocall dom-node :getBoundingClientRect))

(defn some-list-thing []
  (let [refs (r/atom nil)]
    (r/create-class
      {:component-will-receive-props
       (fn [this]
         (when-let [children (some-> @refs js/$ (ocall :children))]
           (println "for example" (map :top (map (comp obj->clj get-bounding-client-rect) (array-seq children))))))
       :reagent-render
       (fn [c]
         (into [:div {:ref (fn [e] (reset! refs e))}] (r/children (r/current-component))))})))

joshkh20:02:23

be careful with into though! someone correct me if i'm wrong, but unless you manually provide keys to the children components then they'll inherit their index as a key, and that can cause some unexpected rendering results when swapping existing elements in a collection.

justinlee20:02:56

@joshkh a couple of questions: (1) doesn’t the ref callback blow away the ref each time? it seems like you’ll just be left with the last child that mounts instead of a vector/map of refs. (2) what is js/$? (3) all those o* calls are cljs-oops?

joshkh20:02:56

yup, it blows away the previous ref every time it renders, but in my case that should be fine. :component-will-receive-props fires prior to the render, and since the previous render stored the parent dom node i can access it's old children dom nodes before it updates / paints. js/$ is a reference to jquery (a javascript library already on the page), and yup.. the o calls are cljs-oops related. i've been burned by advanced compilation in the past. 😉

joshkh21:02:35

oh, regarding the "last child that mounts" comment, it's actually just (re)storing a reference to the parent component which i'm then stepping into to find the directly descending dom nodes using jquery. for what it's worth i'm trying to port this to reagent: https://medium.com/developers-writing/animating-the-unanimatable-1346a5aab3cd

justinlee21:02:30

i’ll read that article but i have been using React Flip Move to get something like that working

joshkh21:02:41

it's surprisingly tricky when you can't (shouldn't?) manipulate dom nodes directly

joshkh21:02:27

i underestimated how complex that component is 😉

justinlee21:02:04

omg this is complicated

justinlee21:02:12

i think i’m glad i used the library 🙂

justinlee21:02:05

oh this is the guy that wrote react flip move. duh okay.

justinlee21:02:57

by the way that library works great with reagent and is pretty straightforward to use

joshkh21:02:22

oh yeah? that might work for me in the mean time. do you have an example of how it can be used via cljs/reagent?

justinlee21:02:15

something like this

(defn listy-component [things]
  [(reagent/adapt-react-class js/FlipMove)
   {:duration 500
    :easing "ease"}
   (map
     (fn [thing]
       (with-meta
         [thing-component
           (:id thing)
           (:name thing)]
         {:key (:id thing)}))
     things)])

joshkh21:02:06

how have i missed adapt-react-class this entire time? thank you. 🙂

justinlee21:02:11

you gotta read those release notes like they were handed down from god on a stone tablet. one day, when I actually understand reagent, I will take all of the release notes and they re-frame documentation specific to reagent and submit a PR

joshkh21:02:29

the hero we need.

justinlee21:02:54

i’m going to do that of cljs-oops too… one of these days 🙂