Skip to content

Instantly share code, notes, and snippets.

@isaksky

isaksky/no-stutter.cljs

Last active Sep 17, 2019
Embed
What would you like to do?
Non stuttering text control in re-frame
(require '[reagent.ratom :as ra])
(require '[reagent.core :as reagent])
(require '[re-frame.core :as rf])
(defn non-stuttering-text-control [props]
(let [text-value-atom (atom "")
outside-change-counter (ra/atom 0)
to-dispose (atom [])]
(fn [props]
(reagent/create-class
{:display-name "non-stuttering-text-control"
:component-will-mount
(fn [this]
(let [props (reagent/props this)
text-sub (:text-value-sub props)]
(reset! text-value-atom @text-sub)
(swap!
to-dispose
conj
(ra/run!
(let [text @text-sub]
(when-not (= text @text-value-atom)
(js/console.log "Got new value from app-state, resetting local state. Counter: " @outside-change-counter #js [text @text-value-atom])
(swap! outside-change-counter inc)
(reset! text-value-atom text)
))))))
:component-will-unmount
(fn [this]
(doseq [disposable @to-dispose]
(ra/dispose! disposable)))
:reagent-render
(fn [props]
[:input.border.border-gray-500
{:key @outside-change-counter
:default-value @text-value-atom
:on-blur (fn [e]
(let [text (.. e -target -value)]
(js/console.log "hm" (:text-change-event props))
(reset! text-value-atom text)
(rf/dispatch (conj (:text-change-event props) text))))}])}))))
;; Example usage:
[non-stuttering-text-control
{:text-value-sub (rf/subscribe [::form-value :text])
:text-change-event [::set-form-value :text]}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment