Use js-obj/aset/aget for props and state

This commit is contained in:
Dan Holmsand 2014-01-08 16:00:21 +01:00
parent c6b56a7a76
commit 5818976f78
2 changed files with 37 additions and 42 deletions

View File

@ -1,56 +1,53 @@
(ns cloact.impl.component (ns cloact.impl.component
(:require [cloact.impl.template :as tmpl] (:require [cloact.impl.template :as tmpl
:refer [cljs-props cljs-children React]]
[cloact.impl.util :as util] [cloact.impl.util :as util]
[cloact.ratom :as ratom] [cloact.ratom :as ratom]
[cloact.debug :refer-macros [dbg prn]])) [cloact.debug :refer-macros [dbg prn]]))
(def React tmpl/React)
(def cljs-state "cljsState")
;;; Accessors ;;; Accessors
(defn state [this]
(aget this cljs-state))
(defn replace-state [this new-state] (defn replace-state [this new-state]
;; Don't use React's replaceState, since it doesn't play well ;; Don't use React's replaceState, since it doesn't play well
;; with clojure maps ;; with clojure maps
(let [old-state (.-cljsState this)] (let [old-state (state this)]
(when-not (identical? old-state new-state) (when-not (identical? old-state new-state)
(set! (.-cljsState this) new-state) (aset this cljs-state new-state)
(.forceUpdate this)))) (.forceUpdate this))))
(defn set-state [this new-state] (defn set-state [this new-state]
(replace-state this (merge (.-cljsState this) new-state))) (replace-state this (merge (state this) new-state)))
(defn state [this]
(.-cljsState this))
(defn js-props [C] (defn js-props [C]
(aget C "props")) (aget C "props"))
(defn props-in-props [props] (defn props-in-props [props]
(-> props .-cljsProps)) (aget props cljs-props))
(defn cljs-props [C] (defn get-props [C]
(-> C js-props props-in-props)) (-> C js-props props-in-props))
(defn get-children [C] (defn get-children [C]
(-> C js-props .-cljsChildren)) (->> C js-props (aget cljs-children)))
(defn replace-props [C newprops] (defn replace-props [C newprops]
(let [obj (js-obj)] (.setProps C (js-obj cljs-props newprops)))
(set! (.-cljsProps obj) newprops)
(.setProps C obj)))
(defn set-props [C newprops] (defn set-props [C newprops]
(replace-props C (merge (cljs-props C) newprops))) (replace-props C (merge (get-props C) newprops)))
(defn get-props [C]
(cljs-props C))
;;; Function wrapping ;;; Function wrapping
(defn do-render [C f] (defn do-render [C f]
(let [res (f (cljs-props C) C) (let [res (f (get-props C) C)
conv (if (vector? res) conv (if (vector? res)
(tmpl/as-component res) (tmpl/as-component res)
(if (fn? res) (if (fn? res)
@ -77,7 +74,7 @@
:getInitialState :getInitialState
(fn [C] (fn [C]
(when f (when f
(set! (.-cljsState C) (merge (.-cljsState C) (f C))))) (aset C cljs-state (merge (state C) (f C)))))
:componentWillReceiveProps :componentWillReceiveProps
(fn [C props] (fn [C props]
@ -88,10 +85,10 @@
;; 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 [inprops (aget C "props") (let [inprops (aget C "props")
p1 (.-cljsProps inprops) p1 (aget inprops cljs-props)
c1 (.-cljsChildren inprops) c1 (aget inprops cljs-children)
p2 (.-cljsProps nextprops) p2 (aget nextprops cljs-props)
c2 (.-cljsChildren nextprops)] c2 (aget nextprops cljs-children)]
(if (nil? f) (if (nil? f)
(not (util/equal-args p1 c1 p2 c2)) (not (util/equal-args p1 c1 p2 c2))
;; call f with oldprops newprops oldchildren newchildren ;; call f with oldprops newprops oldchildren newchildren
@ -154,15 +151,12 @@
(let [spec (cljsify body) (let [spec (cljsify body)
res (.createClass React spec) res (.createClass React spec)
f (fn [& args] f (fn [& args]
(let [arg (js-obj) (let [props (nth args 0 nil)
props (nth args 0 nil)
hasmap (map? props) hasmap (map? props)
first-child (if (or hasmap (nil? props)) 1 0)] first-child (if (or hasmap (nil? props)) 1 0)]
(set! (.-cljsProps arg) (if hasmap props {})) (res (js-obj cljs-props (if hasmap props)
(set! (.-cljsChildren arg) cljs-children (if (> (count args) first-child)
(if (> (count args) first-child) (subvec args first-child))))))]
(subvec args first-child)))
(res arg)))]
(set! (.-cljsReactClass f) res) (set! (.-cljsReactClass f) res)
(set! (.-cljsReactClass res) res) (set! (.-cljsReactClass res) res)
f)) f))

View File

@ -7,6 +7,9 @@
(def React reactimport/React) (def React reactimport/React)
(def cljs-props "cljsProps")
(def cljs-children "cljsChildren")
(def isClient (not (nil? (try (.-document js/window) (def isClient (not (nil? (try (.-document js/window)
(catch js/Object e nil))))) (catch js/Object e nil)))))
@ -65,19 +68,19 @@
(defn wrapped-render [this comp id-class] (defn wrapped-render [this comp id-class]
(let [inprops (aget this "props") (let [inprops (aget this "props")
props (.-cljsProps inprops) props (aget inprops cljs-props)
hasprops (or (nil? props) (map? props)) hasprops (or (nil? props) (map? props))
jsargs (->> (.-cljsChildren inprops) jsargs (->> (aget inprops cljs-children)
(map-into-array as-component))] (map-into-array as-component))]
(.unshift jsargs (convert-props props id-class)) (.unshift jsargs (convert-props props id-class))
(.apply comp nil jsargs))) (.apply comp nil jsargs)))
(defn wrapped-should-update [C nextprops nextstate] (defn wrapped-should-update [C nextprops nextstate]
(let [inprops (aget C "props") (let [inprops (aget C "props")
p1 (.-cljsProps inprops) p1 (aget inprops cljs-props)
c1 (.-cljsChildren inprops) c1 (aget inprops cljs-children)
p2 (.-cljsProps nextprops) p2 (aget nextprops cljs-props)
c2 (.-cljsChildren nextprops)] c2 (aget nextprops cljs-children)]
(not (util/equal-args p1 c1 p2 c2)))) (not (util/equal-args p1 c1 p2 c2))))
(defn wrap-component [comp extras] (defn wrap-component [comp extras]
@ -134,11 +137,9 @@
hasmap (map? props) hasmap (map? props)
first-child (if (or hasmap (nil? props)) 2 1) first-child (if (or hasmap (nil? props)) 2 1)
c (as-class tag) c (as-class tag)
jsprops (js-obj)] jsprops (js-obj cljs-props (if hasmap props)
(set! (.-cljsProps jsprops) (if hasmap props {})) cljs-children (if (> (count v) first-child)
(set! (.-cljsChildren jsprops) (subvec v first-child)))]
(if (> (count v) first-child)
(subvec v first-child)))
(when hasmap (when hasmap
(let [key (:key props)] (let [key (:key props)]
(when-not (nil? key) (when-not (nil? key)