Почему Radium не работает с реагентом (Clojurescript)?
Я пытался заставить работать https://github.com/FormidableLabs/radium с реагентом-проектом / реагентом · GitHub, но я зашел в тупик.
Я смог заставить его работать частично, взломав функцию реагента 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
состояние компонента до истины.
Это правильно запускается: 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 как-то блокирует повторный рендеринг при изменении состояния компонента?
1 ответ
Я перевел основной пример кнопки Radium для использования с 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"]])
Главное, что я преобразовал button
компонент реагента к компоненту React (используя reactify-component
), затем пропустил его через радий, а затем преобразовал обратно во что-то, что я потребляю в реагенте (используя adapt-react-class
).
В моем примере hover
работает.
Надеюсь это поможет.
Я разместил рабочую версию на GitHub.