Fork me on GitHub
#reagent
<
2022-04-21
>
Sam Ritchie22:04:31

hey all - I’m trying to wrap a react component with reagent to update the props before passing them on, and having some trouble. Neither of these seem to work:

(defn MyBox [opts & children]
  (into [MB/ContainedMathbox opts] children))

(defn MyBox [opts & children]
  [MB/ContainedMathbox opts children])
While a bare
[MB/ContainedMathbox opts children]
works fine. Here is the error I am seeing: https://gist.github.com/sritchie/bb3f4d8f14a2ea58d8db656ba6df3163 does anyone have advice on a clean way to write components that take children and pass them along? I will also try the r/children method but it feels cleaner to go with this function-callable style.

p-himik22:04:51

What is children in the case where it works?

Sam Ritchie22:04:26

[box/ContainedMathbox
 {:options opts
  :containerStyle {:height "400px" :width "100%"}
  :ref (mb/opts->setup
        {:background-color 0xeeeeee
         :max-distance 4
         :camera-position [2.5 1 2.5]
         :scale 720 :focus 1})}
 [box/Cartesian
  {:range [[0 1] [0 1] [0 1]]
   :scale [1 1 1]}
  [box/Volume
   {:id id
    :width width-rez
    :bufferWidth width-rez
    :height height-rez
    :bufferHeight height-rez
    :depth depth-rez
    :bufferDepth depth-rez
    :items 1
    :channels 4
    :live false
    :expr (fn [emit x y z]
            (emit x y z opacity))}]
  [box/Point
   {:points (str "#" id)
    :colors (str "#" id)
    :color 0xffffff
    :size size}]]]

Sam Ritchie22:04:15

@U2FRKM4TW so I wanted to start by writing a function that could replace box/ContainedMathbox with box/MyBox and otherwise be exactly the same code form

p-himik22:04:39

So you're passing a single child, and it works. The error seems to be from the case of the second defn. What's the error in the case of into?

p-himik22:04:02

And how are you using MyBox in the case with into?

Sam Ritchie22:04:14

in the case with into, I am using it as

(defn MyBox [opts & children]
  (into [MB/ContainedMathbox opts] children))

[box/MyBox <same 2 args>]

Sam Ritchie22:04:54

and the error is, I BELIEVE, the same in both of my MyBox cases but let me see, one sec

p-himik22:04:56

The into version should work as it will produce the exact same Hiccup.

Sam Ritchie22:04:01

that’s what I thought too!

Sam Ritchie22:04:11

these are both errors, first and second correspond to

(defn MyBox1 [opts & children]
  (into [MB/ContainedMathbox opts] children))

(defn MyBox2 [opts & children]
  [MB/ContainedMathbox opts children])

Sam Ritchie22:04:20

I am using these in #clerk so maybe something strange is going on in that stack

p-himik22:04:22

The errors are different - the second one is "more incorrect". :) Not sure why the first one doesn't work...

Sam Ritchie22:04:30

it is odd, right?

p-himik22:04:00

Where does box/ContainedMathbox come from? It's that React component, right?

Sam Ritchie22:04:32

this must be something with the #clerk layer

Sam Ritchie22:04:35

if I JUST DO THIS:

Sam Ritchie22:04:42

(defn MyBox3 [opts child]
  [MB/ContainedMathbox opts child])

Sam Ritchie22:04:00

and then call it as a function: (mbr/MyBox3 <same 2 arguments>), so I get a vector back:

Sam Ritchie22:04:34

I get

"Assert failed: Invalid Hiccup form: [#js {\"$$typeof\" #object[Symbol(react.forward_ref)], :render #object[Function]} {:options {:plugins [\"core\" \"controls\" \"cursor\"], :controls {:klass OrbitControls}, :camera {}}, :containerStyle {:height \"400px\", :width \"100%\"}, :ref #object[Function]} [#object[reagent.impl.template.NativeWrapper] {:range [[0 1] [0 1] [0 1]], :scale [1 1 1]} [#object[reagent.impl.template.NativeWrapper] {:bufferWidth 10, :channels 4, :bufferDepth 11, :width 10, :bufferHeight 5, :expr sci.impl.fns.fun_._arity_4, :id \"volume\", :depth 11, :live false, :items 1, :height 5}] [#object[reagent.impl.template.NativeWrapper] {:points \"#volume\", :colors \"#volume\", :color 16777215, :size 20}]]]\n (in nextjournal.clerk.sci_viewer.inspect)\n(valid-tag? tag)"

p-himik22:04:41

If MB/ContainedMathbox is a React component and not a Reagent one, then I'm surprised it works. Try your initial into approach but add :> in front of MB/....

Sam Ritchie22:04:43

as an error message. but it is quite confusing

p-himik22:04:09

Reagent doesn't work with React components just like that - you have to either use :> or adapt-react-class (if it's a class component).

Sam Ritchie22:04:11

oh, sorry, it is actually a component wrapped in (r/adapt-react-class ...)

p-himik22:04:44

Weird. If you create a minimal reproducible example, I'll take a closer look.

Sam Ritchie22:04:56

thanks, I will see if I can get it done without the clerk layer

Sam Ritchie03:04:11

@U2FRKM4TW I found my issue! you had basically found it before. because I was using clerk I was making changes on the server side (and sending them to the client) and on the client side; I just realized that on my cljs-only changes, my namespace prefix was referring to the original js components, NOT to my wrapped components via adapt-react-class. it all works when I properly use :>

👍 1