August 28, 2019
By: Kevin

React和Reagent交互

  1. Reagent Render 函数
  2. React Element
  3. React Component 和 Reagent Component

使用AntD/AntDMobile之类的React库,需要我们了解React和Reagent的关系, 需要两者频繁交互, 本文需要需要理下面概念之间的关系:

  • Reagent Render
  • Reagent Component
  • Hiccup
  • React Component
  • React Element

好,让我们开始:

(require '[reagent.core :as r])

Reagent Render 函数

文档:

(doc r/render)

reagent.core/render函数接受 Hiccup 或者 React Element。

  1. react element的情况
(require '[reagent.core :as r])
(r/render-component (r/create-element "button"
                     #js {:onClick #(js/alert "哈喽...")}
                     "我会说哈喽"
                     ) js/klipse-container)
  1. Hiccup的情况: 一旦render发现要render的是一个Hiccup它会调用r/as-element把它转化为一个 React Element
(require '[reagent.core :as r])
;; 下面两种其实是等价的
(r/render-component [:button {:on-click #(js/alert "哈喽...")}
                     "我会说哈喽"] js/klipse-container)
(r/render-component (r/as-element [:button {:on-click #(js/alert "哈喽...")}
                                   "我会说哈喽"]) js/klipse-container)

r/as-element的文档:

(doc r/as-element)

React Element

React Element由r/create-element函数创建,文档:

(doc r/create-element)

reagent.core/create-element函数会调用React的createElement函数。 有四种方式来创建同一个element。

(defn integration []
  [:div
   [:div.foo "Hello " [:strong "world"]]

   (r/create-element "div"
                     #js{:className "foo"}
                     "Hello "
                     (r/create-element "strong"
                                        #js{}
                                        "world"))

   (r/create-element "div"
                     #js{:className "foo"}
                     "Hello "
                     (r/as-element [:strong "world"]))

   [:div.foo "Hello " (r/create-element "strong"
                                        #js{}
                                        "world")]])

[integration]

React Component 和 Reagent Component

React Component来自于第三方的React UI库,典型的比如AntD。这些组件需要转成Reagent Component才可以正常使用,这个场景非常普遍。

r/adapt-react-class把一个react component转化为hiccup form的第一个元素,就像一个普通的Reagent 函数一样

与之相反,Reagent Component也可以通过r/reactify-component转化为React Component。

(defn exported [props]
  [:div "Hi, " (:name props)])

(def react-comp (r/reactify-component exported))

(defn could-be-jsx []
  (r/create-element react-comp #js{:name "world"}))

[could-be-jsx]
(defn hi []
  [(r/adapt-react-class react-comp)
   {:name "world"}])
[hi]
(defn hi []
  [:> react-comp
     {:name "world"}])
[hi]
Tags: Reagent react clojurescript