为什么 Radium 不适用于 Reagent (Clojurescript)?
Why Radium doesn't work with Reagent (Clojurescript)?
我正试图开始工作FormidableLabs/radium · GitHub with reagent-project/reagent · GitHub,但我走到了死胡同。
我可以通过 "hacking" 试剂函数 create-class
像这样让它部分工作(它几乎和原来的一样,我只是添加了 js/Radium
包装器)。
(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))
然后我为组件做了这样的功能
(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"])}))
我在其他一些试剂渲染函数的某处使用它,例如:[radium/radium]
- 因此,将样式矢量合并在一起效果很好(这就是 Radium 功能)。
- 媒体查询也有效,但仅在第一次渲染时,当我更改屏幕尺寸时它不会动态反应。
:hover :focus :active
根本不起作用
我正在研究 Radium 代码以找出问题所在。
好兆头是 Radium 正确地将 onMouseEnter
onMouseLeave
道具分配给组件并将组件的 :hover
状态设置为 true。
这被正确触发:https://github.com/FormidableLabs/radium/blob/master/modules/resolve-styles.js#L412
问题是 render
函数,它应该根据新状态(由 Radium 更改)重新渲染组件,根本没有被触发。
这个 render
函数:
https://github.com/FormidableLabs/radium/blob/master/modules/enhancer.js#L22
而当我 运行 JS Radium 示例(没有 Clojurescript 和 Reagent)时,此渲染函数会在每个 onMouseEnter
onMouseLeave
上触发。完全没有试剂。
当组件状态改变时,Reagent 是否以某种方式阻止重新渲染?
我已经翻译了与 Reagent 一起使用的基本按钮 Radium 示例:
(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"]])
关键是我将 button
试剂组件转换为 React 组件(使用 reactify-component
),然后通过 Radium 传递它,然后将其转换回我在试剂中消耗的东西(使用 adapt-react-class
).
在我的示例中,hover
有效。
希望这对您有所帮助。
我已将工作版本放在 GitHub。
我正试图开始工作FormidableLabs/radium · GitHub with reagent-project/reagent · GitHub,但我走到了死胡同。
我可以通过 "hacking" 试剂函数 create-class
像这样让它部分工作(它几乎和原来的一样,我只是添加了 js/Radium
包装器)。
(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))
然后我为组件做了这样的功能
(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"])}))
我在其他一些试剂渲染函数的某处使用它,例如:[radium/radium]
- 因此,将样式矢量合并在一起效果很好(这就是 Radium 功能)。
- 媒体查询也有效,但仅在第一次渲染时,当我更改屏幕尺寸时它不会动态反应。
:hover :focus :active
根本不起作用
我正在研究 Radium 代码以找出问题所在。
好兆头是 Radium 正确地将 onMouseEnter
onMouseLeave
道具分配给组件并将组件的 :hover
状态设置为 true。
这被正确触发:https://github.com/FormidableLabs/radium/blob/master/modules/resolve-styles.js#L412
问题是 render
函数,它应该根据新状态(由 Radium 更改)重新渲染组件,根本没有被触发。
这个 render
函数:
https://github.com/FormidableLabs/radium/blob/master/modules/enhancer.js#L22
而当我 运行 JS Radium 示例(没有 Clojurescript 和 Reagent)时,此渲染函数会在每个 onMouseEnter
onMouseLeave
上触发。完全没有试剂。
当组件状态改变时,Reagent 是否以某种方式阻止重新渲染?
我已经翻译了与 Reagent 一起使用的基本按钮 Radium 示例:
(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"]])
关键是我将 button
试剂组件转换为 React 组件(使用 reactify-component
),然后通过 Radium 传递它,然后将其转换回我在试剂中消耗的东西(使用 adapt-react-class
).
在我的示例中,hover
有效。
希望这对您有所帮助。
我已将工作版本放在 GitHub。