Fork me on GitHub
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: 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.


What is children in the case where it works?

Sam Ritchie22:04:26

 {: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})}
  {:range [[0 1] [0 1] [0 1]]
   :scale [1 1 1]}
   {: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))}]
   {: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


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?


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


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


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?


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


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)"


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


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 ...)


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