Created
February 17, 2017 15:46
-
-
Save wildermuthn/c99e4e79b8cb073243fdffc6df0de41f to your computer and use it in GitHub Desktop.
Reagent interop, the worst!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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