I am trying to understand how input fields work in Reagent.
I first tried to bind on-change
to a simple function that changes underlying atom:
(defonce app-state
(reagent/atom "Teodor"))
(defn page [ratom]
[:div
[:p
"Please enter your name: "
[:input {:on-change #(swap! ratom %)
:value @ratom}]]
[:p "Your name is " @ratom]])
... which did not work. This, however, does:
(defonce app-state
(reagent/atom "Teodor"))
(defn page [ratom]
[:div
[:p
"Please enter your name: "
[:input {;:on-change #(swap! ratom %)
:on-change (fn [evt]
(reset! ratom (-> evt .-target .-value)))
:value @ratom}]]
[:p "Your name is " @ratom]])
I've managed to desugar the ->
macro:
(fn [evt]
(reset! ratom (-> evt .-target .-value)))
;; is the same as
(fn [evt]
(reset!
ratom
(.-value (.-target evt))))
.-value
and .-target
do?.-value
and .-target
?The evt
that is coming into your function is a JavaScript event object. .-target
and .-value
are the JavaScript DOM properties that allow you to access the underlying value that the event is holding.
Here you are in the world of JavaScript interop, so you will have to go to JavaScript for the documentation.
As far as the complicated semantics of using the ->
macro or not: that's just handy for people who like to unpeel properties from left to right as they read. The ->
macro will be making your code look similar to the equivalent JavaScript code.