Make set-state etc async as well, by using an atom

This commit is contained in:
Dan Holmsand 2014-02-15 11:48:12 +01:00
parent 305fc73d8a
commit 2bb32eb21f
3 changed files with 20 additions and 14 deletions

View File

@ -71,12 +71,14 @@ Everything is optional, except :render.
"Set state of a component." "Set state of a component."
[this new-state] [this new-state]
(assert (util/reagent-component? this)) (assert (util/reagent-component? this))
(assert (or (nil? new-state) (map? new-state)))
(comp/replace-state this new-state)) (comp/replace-state this new-state))
(defn set-state (defn set-state
"Merge component state with new-state." "Merge component state with new-state."
[this new-state] [this new-state]
(assert (util/reagent-component? this)) (assert (util/reagent-component? this))
(assert (or (nil? new-state) (map? new-state)))
(comp/set-state this new-state)) (comp/set-state this new-state))
@ -103,10 +105,10 @@ Everything is optional, except :render.
[this] [this]
(.getDOMNode this)) (.getDOMNode this))
(defn ref [parent ref child] (defn ref [parent key child]
(assert (util/reagent-component? parent)) (assert (util/reagent-component? parent))
(assert (keyword? ref) (str "Ref must be a keyword, not " (pr-str ref))) (assert (keyword? key) (str "Key must be a keyword, not " (pr-str key)))
(tmpl/make-ref-component parent ref child)) (tmpl/make-ref-component parent key child))
(defn refs [this] (defn refs [this]
(assert (util/reagent-component? this)) (assert (util/reagent-component? this))

View File

@ -12,19 +12,22 @@
;;; State ;;; State
(defn state-atom [this]
(let [sa (aget this cljs-state)]
(if-not (nil? sa)
sa
(aset this cljs-state (ratom/atom nil)))))
(defn state [this] (defn state [this]
(aget this cljs-state)) (deref (state-atom this)))
(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 (state this)] (reset! (state-atom this) new-state))
(when-not (identical? old-state new-state)
(aset this cljs-state new-state)
(.forceUpdate this))))
(defn set-state [this new-state] (defn set-state [this new-state]
(replace-state this (merge (state this) new-state))) (swap! (state-atom this) merge new-state))
;;; Rendering ;;; Rendering
@ -64,8 +67,7 @@
:getInitialState :getInitialState
(fn [] (fn []
(this-as C (this-as C
(when f (set-state C (f C))))
(aset C cljs-state (merge (state C) (f C))))))
:componentWillReceiveProps :componentWillReceiveProps
(fn [props] (fn [props]

View File

@ -71,7 +71,7 @@
(when isClient (when isClient
(let [ran (atom 0) (let [ran (atom 0)
comp (reagent/create-class comp (reagent/create-class
{:get-initial-state (fn []) {:get-initial-state (fn [] {:foo "initial"})
:render :render
(fn [] (fn []
(let [this (reagent/current-component)] (let [this (reagent/current-component)]
@ -80,12 +80,14 @@
(with-mounted-component (comp) (with-mounted-component (comp)
(fn [C div] (fn [C div]
(swap! ran inc) (swap! ran inc)
(is (found-in #"hi " div)) (is (found-in #"hi initial" div))
(reagent/set-state C {:foo "there"}) (reagent/replace-state C {:foo "there"})
(rflush)
(is (found-in #"hi there" div)) (is (found-in #"hi there" div))
(reagent/set-state C {:foo "you"}) (reagent/set-state C {:foo "you"})
(rflush)
(is (found-in #"hi you" div)))) (is (found-in #"hi you" div))))
(is (= 4 @ran))))) (is (= 4 @ran)))))