Form 2 Parameters in ClojureScript
Today I was working on a bug that was caused by my component not utilizing the most recent rendering of a resource. After messing around a bit with the component’s parameters, I realized the problem and how it needed to be fixed.
Let’s say I have a person
map with the following structure:
{:kind :person
:name "Ronald McDonald"
:age 42
:favorite-color "red"}
Now let’s say I have this component that changes the name of a person:
(defn name-input [person]
(let [person-atom (reagent/atom person)]
(fn []
[:form
[:fieldset
[:input
{:type "text"
:on-change (partial change-name person-atom)
:value (:name @person-atom)}]]])))
As this component currently exists, any time the textbox is changed, some
sort of update will occur. So if the text is changed to Ronald Reagen
,
then person-atom
will be updated with the name, Ronald Reagen, and
further updates can be sent over to a server for further processing.
Now what if somewhere else in the code, the age was changed to 35
? How does
that affect our current data? Well, our name-input
was initialized with
the entire person
, in the person-atom
. So this will not change and will
retain 42
as the age.
Our data is inconsistent–This is not good! In one part of the code, the age is 35 but in another part it’s still 42! What can we do to solve this? Notice how in our component, we’re returning a function.
This function can take parameters, which will be identical to the parameters
passed into the name-input
function. Each time the component is re-rendered,
the latest person
will be passed into that function.
So instead of creating a person-atom
, let’s create an atom for the name
and pass both the person
and the name
in to the :on-change
function.
(defn name-input [person]
(let [name (reagent/atom (:name person))]
(fn [person]
[:form
[:fieldset
[:input
{:type "text"
:on-change (partial change-name person name)
:value @name}]]])))
And that’s it! Now any time our component is re-rendered, our :on-change
function will have a person
that is consistent with the rest of the application.