Skip to content

Instantly share code, notes, and snippets.

@wildermuthn
Created February 17, 2017 15:46
Show Gist options
  • Save wildermuthn/c99e4e79b8cb073243fdffc6df0de41f to your computer and use it in GitHub Desktop.
Save wildermuthn/c99e4e79b8cb073243fdffc6df0de41f to your computer and use it in GitHub Desktop.
Reagent interop, the worst!
;; Interop is, holy hell, the worst. See below for a deep dive into r interop. If ever there was a case for Om.Next...
(comment
(def r-create-class-r-render
(r/create-class
{:r-render
(fn [a b]
[root a b])}))
(def r-create-class-react-render
(r/create-class
{:render
(fn [this]
(let [children (r/children this)]
[:div {:style {:color :red}}
(apply root children)]))}))
(def pure-react-class (.createClass js/React
#js{"render"
(fn []
(.createElement js/React
"div"
nil
"A pure react class"))}))
(def pure-react-class-with-r-children
(.createClass js/React
#js{"render"
(fn [& argv]
(this-as this
(let [props (.-props this)
children (.-children props)]
(l/info argv)
(l/info props)
(l/info children)
(.createElement js/React
"div"
nil
"A pure react class with r children"
(r/as-element (js->clj children))))))}))
(def pure-react-element (.createElement js/React
"div"
nil
"A pure react element"))
(def pure-react-class-to-convert (.createClass js/React
#js{"render"
(fn []
(.createElement js/React
"div"
nil
"A pure react class, converted"))}))
(def pure-react-class-with-r-children-to-convert
(.createClass js/React
#js {"render"
(fn [& argv]
(this-as this
(let [props (.-props this)
children (.-children props)]
(l/info argv)
(l/info props)
(l/info children)
(.createElement js/React
"div"
nil
"A converted class with children"
(r/as-element (js->clj children))))))}))
(def converted-class (r/adapt-react-class pure-react-class-to-convert))
(def converted-class-with-children (r/adapt-react-class pure-react-class-with-r-children-to-convert))
(defn text-div [coll]
(l/info coll)
(let [children (-> coll :children js->clj)]
(l/info children)
[:div "A reactified text div"]))
(def reactified-r-component (r/reactify-component text-div))
(def yo [:div "yo"])
(def pure-react-class-using-reactified
(.createClass js/React
#js {"render"
(fn []
(.createElement js/React
reactified-r-component
nil
"child"
"child2"
yo))}))
(def r-as-element (r/as-element [:div "r as element"]))
(comment
[:div
[r-create-class-r-render "a " "create-class with r-render"]
; [:> r-create-class-r-render "a " "create-class with r-render"] FAIL
[r-create-class-react-render "a " [:span {:style {:color :blue}} "create-class with render!"]]
[:> r-create-class-react-render "a " "create-class with render using interop!"]
[:> r-create-class-react-render "a " [:span {:style {:color :blue}} "create-class with render!"]]
[:> pure-react-class]
; [pure-react-class] FAIL
[converted-class]
; [converted-class :a :b] FAIL - renders, but :a :b are not passed along in r style
[:> pure-react-class-with-r-children #js [:div {:style {:padding-left "10px"}}
"nested"
[:div "elements"]]]
; [pure-react-class.... ] FAIL
[converted-class-with-children #js [:div {:style {:padding-left "10px"}}
"nested"
[:div "elements"]]]
;[converted-class-with-children [:div {:style {:padding-left "10px"}}
; "nested"
; [:div "elements"]]]
; FAIL without #js
pure-react-element
; [pure-react-element] FAIL
[:div "div keyword"]
r-as-element
; [r-as-element] FAIL
[:div
"r as element inside of div"
[:div
{:style {:padding-left "10px"}}
r-as-element]]
[:> reactified-r-component]
; [reactified-r-component] FAIL - renders, but normally a class would fail
[:> pure-react-class-using-reactified]])
"If you use r's create-class, it injects things that allow you to use it like normal hiccup using r-render, or elements using react's render. If you use react's render, then you can also use it with the :> interop.
Reagent always injects the children into props when it is inside a hiccup form, but it does so as a javascript object, and you can only have one child, like React.
- react elements
- react classes defined outside of r
- react classes defined with r helpers
- clojure functions that return hiccup
If you use r utils, you can return valid hiccup. But unless you use the r-render function, you have to pluck out the props/children using the r utils, in which case you can still pass valid hiccup syntax for those helpers.
If you don't use r utils, in the case of third party components, then you are stuck manually plucking out everything you need, even using js->clj on children that does get injected by r. But you need to use #js objects for the children.
For adapt-react-class... it doesn't really convert it properly, there's really no point to it, now that the :> operator exists
As for reactifying components, this doesn't mean it automatically works like a r component inside of a react component. It has to obey all the rules that a normal react class would follow, manually plucking out the things it needs, and unable to use the r utilities
So what's this mean for the fucking interop?
Well, I'm dealing with a pure react class. Which means that I have to wrap it up and pass the hiccup children into it.
"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment