August 28, 2019
By: Kevin
React和Reagent交互
使用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。
- react element的情况
(require '[reagent.core :as r])
(r/render-component (r/create-element "button"
#js {:onClick #(js/alert "哈喽...")}
"我会说哈喽"
) js/klipse-container)
- 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]