Sitemap

React: Controlling the Form

3 min readSep 11, 2022

--

I understand and appreciate the reasons for using controlled forms when building out a page in React, but sometimes I start to feel like: “Wow, I’m sure starting to collect a lot of individual variables in state…” Take for example the following list from an online resident directory I’ve been working on recently:

const [lots, setLots] = useState([]);
const [filter, setFilter] = useState(“”);
const [searchBy, setSearchBy] = useState(“displayName”);
const [sortBy, setSortBy] = useState(“lot”);
const [lotsToDisplay, setLotsToDisplay] = useState([]);
const [loggedIn, setLoggedIn] = useState(false);
const [user, setUser] = useState(“”);
const [password, setPassword] = useState(“”);
const [loginError, setLoginError] = useState(false);
const [blankSearch, setBlankSearch] = useState(true);

This starts to feel overwhelming to look at; what are all of these variables holding onto anyway?? If you step away from the project for too long, it can be easy to forget. And even with descriptive names, it’s not clear just by looking which of these variables are serving to hold information for controlled forms, as opposed to (for instance) storing the list of directory entries.

One time in particular while building my code for this site, I started to feel like not only was I collecting too many variables in state, but also that the code was getting suspiciously wet (that is to say, not DRY). I was making a form for adding a new entry to the directory, which asked the user/admin to fill in lot number, first name, last name, spouse/partner name, a string for how to display the names in the entry, pet names, and internal notes.

At first, I set up individual variables in state, with corresponding update functions:

const [newLastName, setNewLastName] = useState(“”)

function handleLastNameUpdate(e) {
const updatedLastName = { …newLastName, lastName: e.target.value }
setNewLastName(updatedLastName);
}

return (
…
<label>
Last Name:
<input
type=”text”
onChange={handleLastNameUpdate}
value={newLastName}
>
</input>
</label>
)

And, the code above is fine, it works. But with seven fields in the form, it results in seven variables and seven helper functions, and they are all essentially identical.

Get Jarod Wilson’s stories in your inbox

Join Medium for free to get updates from this writer.

I had already all but finished building out this bulky code when it occurred to me: once this is all done and the form gets submitted by the user, the information will be stored into the backend as a single object, not as a bunch of discreet variables. … So, couldn’t we just simplify the state down to an object? Then we just have to pass that one object up to the main app upon submission of the form, rather than multiple variables (or compiling the variables into an object only upon form submission).

It makes so much sense!

So I refactored the variables into a single object:

const [newEntry, setNewEntry] = useState(
{
lot: “”,
firstName: “”,
lastName: “”,
partnerName: “”,
displayName: “”,
petName: “”,
notes: “”
})

Now all that was left was making sure that I could update each value as appropriate. To simplify this, I added a name tag to each field in the form, and made sure that it matched the key in my object in state. And voila! A single helper function takes care of the control for the form:

function handleUpdate(e) {
const updateEntry = { …newEntry, [e.target.name]: e.target.value }
setNewEntry(updateEntry);
}

With the added benefit of saving a step to submit the form!

I know this may seem very obvious in retrospect, but I think sometimes we just get bogged down into the code and don’t see the whole picture clearly.

One lesson I plan to take away from this is that I might consider using objects in state in certain other circumstances, as a kind of organizational tool. For instance, it might make sense to hold onto all login-related information in a single object with multiple keys, or all search/sort information. When passing variables between react components, it would probably save some typing, and would make things a little easier to look at.

Then again, I’ll probably discover something even better next time I build out a project like this. Learning is fun!

--

--

Jarod Wilson
Jarod Wilson

Written by Jarod Wilson

0 followers

Theatrical designer, AV professional, and aspiring programmer with a strong emphasis on design.