I try to hang out in the #cljsrn channel on Clojurians Slack to answer questions that I can as they come up, and one in particular that I also puzzled over has recurred: Why is there so much keyboard lag on my TextInput elements? Is this inherent in React Native or ClojureScript?

Fortunately, it’s not. The issue is how you handle the element’s state. Most people start out with something like this:

(defn my-input-element
  []
  (let [first-name (r/atom (get-user-current-first-name-somehow))]
    (fn []
      [text-input {:value @first-name
                   :on-change-text #(reset! first-name %)}])))

The issue here is that every time you type a character, you’re not just updating your Reagent atom, you’re repainting the entire element over from scratch. Instead, you should just provide a default value and let Reagent and ReactNative handle things separately:

[text-input {:default-value @first-name
             :on-change-text #(reset! first-name %)}]

You will still have the initial state set correctly, but you won’t experience the weird keyboard lag.