为什么 Radium 不能与 Reagent(Clojurescript)一起使用?

8
我试图让 FormidableLabs/radium · GitHubreagent-project/reagent · GitHub 协同工作,但是我陷入了死胡同。
我通过“黑客” reagent 函数 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"])}))

我在其他一些reagent渲染函数中使用它,例如:[radium/radium]

  • 因此,将样式向量合并在一起很好用(这是Radium的功能)。
  • 媒体查询也可以,但只在第一次渲染时有效,当我改变屏幕大小时不会动态地响应。
  • :hover :focus :active根本不起作用。

我在研究Radium代码以找出问题所在。一个好的迹象是,Radium将onMouseEnteronMouseLeave props正确分配给组件,并将组件的: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是否会在组件状态更改时阻止重新渲染?
1个回答

5
我已将基本按钮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 reagent组件转换为React组件(使用reactify-component),然后通过Radium传递它,然后将其转换回我在reagent中使用的东西(使用adapt-react-class)。
在我的示例中,hover可以工作。
希望这有所帮助。
我已经将可工作版本放在GitHub上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接