mirror of https://github.com/status-im/reagent.git
Allow output from create-class to be used directly by React
This commit is contained in:
parent
4601b37ec5
commit
533c05aaca
|
@ -3,7 +3,7 @@
|
||||||
[reagent.impl.batching :as batch]
|
[reagent.impl.batching :as batch]
|
||||||
[reagent.ratom :as ratom]
|
[reagent.ratom :as ratom]
|
||||||
[reagent.interop :refer-macros [.' .!]]
|
[reagent.interop :refer-macros [.' .!]]
|
||||||
[reagent.debug :refer-macros [dbg prn dev? warn]]))
|
[reagent.debug :refer-macros [dbg prn dev? warn warn-unless]]))
|
||||||
|
|
||||||
(declare ^:dynamic *current-component*)
|
(declare ^:dynamic *current-component*)
|
||||||
|
|
||||||
|
@ -12,6 +12,16 @@
|
||||||
|
|
||||||
;;; Argv access
|
;;; Argv access
|
||||||
|
|
||||||
|
(defn shallow-obj-to-map [o]
|
||||||
|
(let [ks (js-keys o)
|
||||||
|
len (alength ks)]
|
||||||
|
(persistent!
|
||||||
|
(loop [m (transient {}) i 0]
|
||||||
|
(if (< i len)
|
||||||
|
(let [k (aget ks i)]
|
||||||
|
(recur (assoc! m (keyword k) (aget o k)) (inc i)))
|
||||||
|
m)))))
|
||||||
|
|
||||||
(defn extract-props [v]
|
(defn extract-props [v]
|
||||||
(let [p (nth v 1 nil)]
|
(let [p (nth v 1 nil)]
|
||||||
(if (map? p) p)))
|
(if (map? p) p)))
|
||||||
|
@ -22,11 +32,13 @@
|
||||||
(if (> (count v) first-child)
|
(if (> (count v) first-child)
|
||||||
(subvec v first-child))))
|
(subvec v first-child))))
|
||||||
|
|
||||||
(defn props-argv [p]
|
(defn props-argv [c p]
|
||||||
(.' p :argv))
|
(if-some [a (.' p :argv)]
|
||||||
|
a
|
||||||
|
[c (shallow-obj-to-map p)]))
|
||||||
|
|
||||||
(defn get-argv [c]
|
(defn get-argv [c]
|
||||||
(.' c :props.argv))
|
(props-argv c (.' c :props)))
|
||||||
|
|
||||||
(defn get-props [c]
|
(defn get-props [c]
|
||||||
(-> (get-argv c) extract-props))
|
(-> (get-argv c) extract-props))
|
||||||
|
@ -37,6 +49,12 @@
|
||||||
(defn reagent-component? [c]
|
(defn reagent-component? [c]
|
||||||
(-> (get-argv c) nil? not))
|
(-> (get-argv c) nil? not))
|
||||||
|
|
||||||
|
(defn cached-react-class [c]
|
||||||
|
(.' c :cljsReactClass))
|
||||||
|
|
||||||
|
(defn cache-react-class [c constructor]
|
||||||
|
(.! c :cljsReactClass constructor))
|
||||||
|
|
||||||
|
|
||||||
;;; State
|
;;; State
|
||||||
|
|
||||||
|
@ -137,22 +155,22 @@
|
||||||
;; Don't care about nextstate here, we use forceUpdate
|
;; Don't care about nextstate here, we use forceUpdate
|
||||||
;; when only when state has changed anyway.
|
;; when only when state has changed anyway.
|
||||||
(let [old-argv (.' c :props.argv)
|
(let [old-argv (.' c :props.argv)
|
||||||
new-argv (.' nextprops :argv)]
|
new-argv (.' nextprops :argv)
|
||||||
(if (nil? f)
|
no-argv (or (nil? old-argv) (nil? new-argv))]
|
||||||
(or (nil? old-argv)
|
(cond
|
||||||
(nil? new-argv)
|
(nil? f) (or no-argv (not= old-argv new-argv))
|
||||||
(not= old-argv new-argv))
|
no-argv (f c (get-argv c) (props-argv c nextprops))
|
||||||
(f c old-argv new-argv))))))
|
:else (f c old-argv new-argv))))))
|
||||||
|
|
||||||
:componentWillUpdate
|
:componentWillUpdate
|
||||||
(fn [nextprops]
|
(fn [nextprops]
|
||||||
(this-as c
|
(this-as c
|
||||||
(f c (props-argv nextprops))))
|
(f c (props-argv c nextprops))))
|
||||||
|
|
||||||
:componentDidUpdate
|
:componentDidUpdate
|
||||||
(fn [oldprops]
|
(fn [oldprops]
|
||||||
(this-as c
|
(this-as c
|
||||||
(f c (props-argv oldprops))))
|
(f c (props-argv c oldprops))))
|
||||||
|
|
||||||
:componentWillMount
|
:componentWillMount
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -268,8 +286,7 @@
|
||||||
{:pre [(map? body)]}
|
{:pre [(map? body)]}
|
||||||
(let [spec (cljsify body)
|
(let [spec (cljsify body)
|
||||||
res (.' js/React createClass spec)]
|
res (.' js/React createClass spec)]
|
||||||
(util/cache-react-class res res)
|
(cache-react-class res res)))
|
||||||
res))
|
|
||||||
|
|
||||||
(defn component-path [c]
|
(defn component-path [c]
|
||||||
(let [elem (some-> (or (some-> c (.' :_reactInternalInstance))
|
(let [elem (some-> (or (some-> c (.' :_reactInternalInstance))
|
||||||
|
@ -295,23 +312,24 @@
|
||||||
""))
|
""))
|
||||||
""))
|
""))
|
||||||
|
|
||||||
(defn shallow-obj-to-map [o]
|
|
||||||
(into {} (for [k (js-keys o)]
|
|
||||||
[(keyword k) (aget o k)])))
|
|
||||||
|
|
||||||
(def elem-counter 0)
|
(defn fn-to-class [f]
|
||||||
|
(assert (ifn? f) (str "Expected a function, not " (pr-str f)))
|
||||||
|
(warn-unless (not (and (fn? f)
|
||||||
|
(some? (.' f :type))))
|
||||||
|
"Using native React classes directly in Hiccup forms "
|
||||||
|
"is not supported. Use create-element or "
|
||||||
|
"adapt-react-class instead: " (.' f :type)
|
||||||
|
(comp-name))
|
||||||
|
(let [spec (meta f)
|
||||||
|
withrender (assoc spec :reagent-render f)
|
||||||
|
res (create-class withrender)]
|
||||||
|
(cache-react-class f res)))
|
||||||
|
|
||||||
|
(defn as-class [tag]
|
||||||
|
(if-some [cached-class (cached-react-class tag)]
|
||||||
|
cached-class
|
||||||
|
(fn-to-class tag)))
|
||||||
|
|
||||||
(defn reactify-component [comp]
|
(defn reactify-component [comp]
|
||||||
(.' js/React createClass
|
(as-class comp))
|
||||||
#js{:displayName "react-wrapper"
|
|
||||||
:render
|
|
||||||
(fn []
|
|
||||||
(this-as this
|
|
||||||
(as-element
|
|
||||||
[comp
|
|
||||||
(-> (.' this :props)
|
|
||||||
shallow-obj-to-map
|
|
||||||
;; ensure re-render, might get mutable js data
|
|
||||||
(assoc :-elem-count
|
|
||||||
(set! elem-counter
|
|
||||||
(inc elem-counter))))])))}))
|
|
||||||
|
|
|
@ -196,26 +196,6 @@
|
||||||
:id id
|
:id id
|
||||||
:className class}))
|
:className class}))
|
||||||
|
|
||||||
(defn fn-to-class [f]
|
|
||||||
(assert (ifn? f) (str "Expected a function, not " (pr-str f)))
|
|
||||||
(warn-unless (not (and (fn? f)
|
|
||||||
(some? (.' f :type))))
|
|
||||||
"Using native React classes directly in Hiccup forms "
|
|
||||||
"is not supported. Use create-element or "
|
|
||||||
"adapt-react-class instead: " (.' f :type)
|
|
||||||
(comp/comp-name))
|
|
||||||
(let [spec (meta f)
|
|
||||||
withrender (assoc spec :reagent-render f)
|
|
||||||
res (comp/create-class withrender)
|
|
||||||
wrapf (util/cached-react-class res)]
|
|
||||||
(util/cache-react-class f wrapf)
|
|
||||||
wrapf))
|
|
||||||
|
|
||||||
(defn as-class [tag]
|
|
||||||
(if-some [cached-class (util/cached-react-class tag)]
|
|
||||||
cached-class
|
|
||||||
(fn-to-class tag)))
|
|
||||||
|
|
||||||
(defn get-key [x]
|
(defn get-key [x]
|
||||||
(when (map? x)
|
(when (map? x)
|
||||||
;; try catch to avoid clojurescript peculiarity with
|
;; try catch to avoid clojurescript peculiarity with
|
||||||
|
@ -229,7 +209,7 @@
|
||||||
(-> v (nth 1 nil) get-key)))
|
(-> v (nth 1 nil) get-key)))
|
||||||
|
|
||||||
(defn reag-element [tag v]
|
(defn reag-element [tag v]
|
||||||
(let [c (as-class tag)
|
(let [c (comp/as-class tag)
|
||||||
jsprops #js{:argv v}]
|
jsprops #js{:argv v}]
|
||||||
(some->> v key-from-vec (.! jsprops :key))
|
(some->> v key-from-vec (.! jsprops :key))
|
||||||
(.' js/React createElement c jsprops)))
|
(.' js/React createElement c jsprops)))
|
||||||
|
|
|
@ -8,12 +8,6 @@
|
||||||
|
|
||||||
;;; Props accessors
|
;;; Props accessors
|
||||||
|
|
||||||
(defn cached-react-class [c]
|
|
||||||
(.' c :cljsReactClass))
|
|
||||||
|
|
||||||
(defn cache-react-class [c constructor]
|
|
||||||
(.! c :cljsReactClass constructor))
|
|
||||||
|
|
||||||
;; Misc utilities
|
;; Misc utilities
|
||||||
|
|
||||||
(defn memoize-1 [f]
|
(defn memoize-1 [f]
|
||||||
|
|
|
@ -487,11 +487,14 @@
|
||||||
(deftest test-reactize-component
|
(deftest test-reactize-component
|
||||||
(let [ae r/as-element
|
(let [ae r/as-element
|
||||||
ce r/create-element
|
ce r/create-element
|
||||||
c1r (fn [p]
|
a (atom nil)
|
||||||
|
c1r (fn [p & args]
|
||||||
|
(reset! a args)
|
||||||
[:p "p:" (:a p) (:children p)])
|
[:p "p:" (:a p) (:children p)])
|
||||||
c1 (r/reactify-component c1r)]
|
c1 (r/reactify-component c1r)]
|
||||||
(is (= (rstr [:p "p:a"])
|
(is (= (rstr [:p "p:a"])
|
||||||
(rstr (ce c1 #js{:a "a"}))))
|
(rstr (ce c1 #js{:a "a"}))))
|
||||||
|
(is (= @a nil))
|
||||||
(is (= (rstr [:p "p:"])
|
(is (= (rstr [:p "p:"])
|
||||||
(rstr (ce c1 #js{:a nil}))))
|
(rstr (ce c1 #js{:a nil}))))
|
||||||
(is (= (rstr [:p "p:"])
|
(is (= (rstr [:p "p:"])
|
||||||
|
@ -500,10 +503,12 @@
|
||||||
(is (= (rstr [:p "p:a" [:b "b"]])
|
(is (= (rstr [:p "p:a" [:b "b"]])
|
||||||
(rstr (ce c1 #js{:a "a"}
|
(rstr (ce c1 #js{:a "a"}
|
||||||
(ae [:b "b"])))))
|
(ae [:b "b"])))))
|
||||||
|
(is (= @a nil))
|
||||||
(is (= (rstr [:p "p:a" [:b "b"] [:i "i"]])
|
(is (= (rstr [:p "p:a" [:b "b"] [:i "i"]])
|
||||||
(rstr (ce c1 #js{:a "a"}
|
(rstr (ce c1 #js{:a "a"}
|
||||||
(ae [:b "b"])
|
(ae [:b "b"])
|
||||||
(ae [:i "i"])))))))
|
(ae [:i "i"])))))
|
||||||
|
(is (= @a nil))))
|
||||||
|
|
||||||
(deftest test-keys
|
(deftest test-keys
|
||||||
(let [a nil ;; (r/atom "a")
|
(let [a nil ;; (r/atom "a")
|
||||||
|
|
Loading…
Reference in New Issue