I have the following reagent component. if i remove the random-uuid i get warnings and if i add them, the input field loses focus after entering a single character! what is going on here? can somebody please help me?
(defn input-fields
[]
[:div
[:div.h1
[:p (str "content of states: " @state)]
[:p "fuck you"]]
(doall
(for [id (range 5)]
[:div #_{:key (random-uuid)}
[:input {
:type :text
:value #_(:foo @state)
(sp/select-one [sp/ATOM :input sp/ALL #(= (:id %) id) :attribute] state)
:on-change (fn [e]
(sp/transform [sp/ATOM :input sp/ALL #(= (:id %) id)]
(fn[x] (assoc x :attribute (-> e .-target .-value))) state))}]
[:input {
:type :text
:value #_(:foo @state)
(sp/select-one [sp/ATOM :input sp/ALL #(= (:id %) id) :value] state)
:on-change (fn [e]
(sp/transform [sp/ATOM :input sp/ALL #(= (:id %) id)]
(fn[x] (assoc x :value (-> e .-target .-value))) state))}]]))
[:input {
:type :button
:value :submit
:on-click (fn [e]
(println "submit placeholder"))}]])
:key
should be a stable value with respect to its contents. try using something like {:key id}
I can't remember if key is required to be a string. you might need {:key (str id)}
numbers should be fine as keys
changing it to a number solved the problem. thanks guys.
was the key changing after each diff?
yes, (random-uuid)
gets run every render so it will produce a new uuid
so it was telling React to blow out whatever DOM element it had created for your :input
and create a new one, resetting the cursor position
i see. makes sense
see https://reactjs.org/docs/reconciliation.html for the "official" explanation
reusing dom nodes is good for performance and it's required for state that's only represented in the dom (like focus and cursor position)