I was trying to get working FormidableLabs/radium · GitHub with reagent-project/reagent · GitHub, but I've come to a dead end.
I was able to get it working partially by "hacking" reagent function create-class
like this (It's almost the same as original, I just added js/Radium
wrapper).
(ns myproject.components.radium
(:require [reagent.core :as r]
[reagent.impl.component :as c]
[reagent.impl.util :as util]
[reagent.interop :refer-macros [.' .!]]))
(defn create-class
[body]
(assert (map? body))
(let [
spec (c/cljsify body)
res (js/Radium (.' js/React createClass spec))
;res (.' js/React createClass spec)
f (fn [& args]
(r/as-element (apply vector res args)))]
(util/cache-react-class f res)
(util/cache-react-class res res)
f))
Then I made function for component like this
(defn radium []
(create-class
{:reagent-render
(fn []
[:button {:style
[{:backgroundColor "red"
:width 500
:height 100
"@media (min-width: 200px)" {:backgroundColor "blue"}
":hover" {:backgroundColor "green"}}
{:height 200}]}
"Heres something"])}))
And I use it somewhere in some other reagent render function like: [radium/radium]
:hover :focus :active
doesn't work at allI was digging in Radium code to found out what's wrong.
Good sign was that Radium properly assigns onMouseEnter
onMouseLeave
props to the component and sets :hover
state of component to true.
This gets properly fired: https://github.com/FormidableLabs/radium/blob/master/modules/resolve-styles.js#L412
The problem is that render
function, which is supposed re-render component based on new state (changed by Radium) is not fired at all.
This render
function:
https://github.com/FormidableLabs/radium/blob/master/modules/enhancer.js#L22
Whereas when I run JS Radium examples (no Clojurescript and Reagent), this render function gets fired on every onMouseEnter
onMouseLeave
. With reagent not at all.
Does Reagent somehow block re-rendering when component state changes?
I've translated the basic button Radium example to be used with Reagent:
(def Radium js/Radium)
(def styles {:base {:color "#fff"
":hover" {:background "#0A8DFF"}}
:primary {:background "#0074D9"}
:warning {:background "#FF4136"}})
(defn button
[data]
(let [kind (keyword (:kind data))]
[:button
{:style (clj->js [(:base styles)
(kind styles)])}
(:children data)]))
(def btn (Radium. (reagent/reactify-component button)))
(def rbtn (reagent/adapt-react-class btn))
(defn hello-world
[]
[:div
[rbtn {:kind :primary} "Hello Primary"]
[rbtn {:kind :warning} "Hello Warning"]])
The key thing is that I converted button
reagent component to a React component (using reactify-component
), then passed it through Radium and then converted it back to something which I consume in reagent (using adapt-react-class
).
In my example, hover
works.
Hope this helps.
I've placed the working version on GitHub.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With