mirror of https://github.com/status-im/reagent.git
Improve managed inputs
Make sure they are reset to their current value just after the next render (if they are not changed during that rendering).
This commit is contained in:
parent
b1bec33448
commit
92fdf36aa5
|
@ -34,22 +34,31 @@
|
|||
(when (.' c :cljsIsDirty)
|
||||
(.' c forceUpdate)))))
|
||||
|
||||
(deftype RenderQueue [^:mutable queue ^:mutable scheduled?]
|
||||
(defn run-funs [a]
|
||||
(dotimes [i (alength a)]
|
||||
((aget a i))))
|
||||
|
||||
(deftype RenderQueue [^:mutable queue ^:mutable scheduled?
|
||||
^:mutable after-render]
|
||||
Object
|
||||
(queue-render [this c]
|
||||
(.push queue c)
|
||||
(.schedule this))
|
||||
(add-after-render [_ f]
|
||||
(.push after-render f))
|
||||
(schedule [this]
|
||||
(when-not scheduled?
|
||||
(set! scheduled? true)
|
||||
(next-tick #(.run-queue this))))
|
||||
(run-queue [_]
|
||||
(let [q queue]
|
||||
(let [q queue aq after-render]
|
||||
(set! queue (array))
|
||||
(set! after-render (array))
|
||||
(set! scheduled? false)
|
||||
(run-queue q))))
|
||||
(run-queue q)
|
||||
(run-funs aq))))
|
||||
|
||||
(def render-queue (RenderQueue. (array) false))
|
||||
(def render-queue (RenderQueue. (array) false (array)))
|
||||
|
||||
(defn flush []
|
||||
(.run-queue render-queue))
|
||||
|
@ -61,6 +70,13 @@
|
|||
(defn mark-rendered [c]
|
||||
(.! c :cljsIsDirty false))
|
||||
|
||||
(defn do-after-flush [f]
|
||||
(.add-after-render render-queue f))
|
||||
|
||||
(defn do-later [f]
|
||||
(do-after-flush f)
|
||||
(.schedule render-queue))
|
||||
|
||||
;; Render helper
|
||||
|
||||
(defn is-reagent-component [c]
|
||||
|
|
|
@ -88,33 +88,39 @@
|
|||
|
||||
;;; Specialization for input components
|
||||
|
||||
(defn input-unmount [this]
|
||||
(.! this :cljsInputValue nil))
|
||||
|
||||
(defn input-set-value [this]
|
||||
(when-some [value (.' this :cljsInputValue)]
|
||||
(.! this :cljsInputDirty false)
|
||||
(let [node (.' this getDOMNode)]
|
||||
(when (not= value (.' node :value))
|
||||
(.! node :value value)))))
|
||||
|
||||
(defn input-handle-change [this on-change e]
|
||||
(let [res (on-change e)]
|
||||
;; Make sure the input is re-rendered, in case on-change
|
||||
;; wants to keep the value unchanged
|
||||
(batch/queue-render this)
|
||||
(when-not (.' this :cljsInputDirty)
|
||||
(.! this :cljsInputDirty true)
|
||||
(batch/do-later #(input-set-value this)))
|
||||
res))
|
||||
|
||||
(defn input-did-update [this]
|
||||
(let [value (.' this :cljsInputValue)]
|
||||
(when-not (nil? value)
|
||||
(let [node (.' this getDOMNode)]
|
||||
(when (not= value (.' node :value))
|
||||
(.! node :value value))))))
|
||||
|
||||
(defn input-render-setup [this jsprops]
|
||||
;; Don't rely on React for updating "controlled inputs", since it
|
||||
;; doesn't play well with async rendering (misses keystrokes).
|
||||
(let [on-change (.' jsprops :onChange)
|
||||
value (when-not (nil? on-change)
|
||||
(.' jsprops :value))]
|
||||
(.! this :cljsInputValue value)
|
||||
(when-not (nil? value)
|
||||
(batch/mark-rendered this)
|
||||
(if (and (.' jsprops hasOwnProperty "onChange")
|
||||
(.' jsprops hasOwnProperty "value"))
|
||||
(let [v (.' jsprops :value)
|
||||
value (if (nil? v) "" v)
|
||||
on-change (.' jsprops :onChange)]
|
||||
(.! this :cljsInputValue value)
|
||||
(js-delete jsprops "value")
|
||||
(doto jsprops
|
||||
(.! :defaultValue value)
|
||||
(.! :value nil)
|
||||
(.! :onChange #(input-handle-change this on-change %))))))
|
||||
(.! :onChange #(input-handle-change this on-change %))))
|
||||
(.! this :cljsInputValue nil)))
|
||||
|
||||
(defn input-component? [x]
|
||||
(let [DOM (.' js/React :DOM)]
|
||||
|
@ -148,8 +154,8 @@
|
|||
|
||||
(defn add-input-methods [spec]
|
||||
(doto spec
|
||||
(.! :componentDidUpdate #(this-as c (input-did-update c)))
|
||||
(.! :componentWillUnmount #(this-as c (batch/dispose c)))))
|
||||
(.! :componentDidUpdate #(this-as c (input-set-value c)))
|
||||
(.! :componentWillUnmount #(this-as c (input-unmount c)))))
|
||||
|
||||
(defn wrap-component [comp extras name]
|
||||
(let [input? (input-component? comp)
|
||||
|
|
Loading…
Reference in New Issue