React Native
Form state
Learn form state management.
A form state object
A form contains several fields: name, email, password. Instead of opening a separate useState for each field, it is cleaner to keep them all in one object state. const [form, setForm] = useState({ name: "", email: "" }); holds every field in a single state.
When you update, you use the object spread: setForm({ ...form, name: "Alex" }). Here ...form copies all existing fields into the new object; name takes its new value. The email field stays unchanged. A single state makes managing the form from one place easy; when you submit you only read the form object. This pattern grows more valuable as the number of fields rises.
Update with a computed property
Sometimes you know which field to update only dynamically. For example the onChangeText handler can take the field name as a parameter. In that case you use a computed property: setForm({ ...form, [field]: value }).
Here the square brackets around [field] turn the value of field into the property name. So if field = "email" then [field]: value becomes email: value. This way a single handler can manage several fields: const handleChange = (field, value) => setForm({ ...form, [field]: value });. This is the most common way to manage form fields from one place. Code duplication drops, readability rises.
Exercise Write two fields with form state
Write a LoginForm component. Start form state with { email: "", password: "" } using useState. Return two TextInputs: the first has value={form.email} and onChangeText={(text) => setForm({ ...form, email: text })}. The second has value={form.password} and onChangeText={(text) => setForm({ ...form, password: text })}. Add the secureTextEntry prop to the second.
Show example solution
import { useState } from "react";
import { TextInput } from "react-native";
function LoginForm() {
const [form, setForm] = useState({ email: "", password: "" });
return (
<>
<TextInput
value={form.email}
onChangeText={(text) => setForm({ ...form, email: text })}
placeholder="Email"
/>
<TextInput
value={form.password}
onChangeText={(text) => setForm({ ...form, password: text })}
placeholder="Password"
secureTextEntry
/>
</>
);
}
Test yourself
-
Update one field with spread
setForm({ ____, name: "Ayşe" });
Show answer
setForm({ ...form, name: "Ayşe" });
-
Match the concept to its role
- form
- Holds all fields
- setForm
- Updates the form object
- ...form
- Opens existing fields
- [field]
- Picks the field name
-
Why use ...form when updating form state?
setForm({ ...form, name: text });
- So the new object is smaller
- To clear the state
- To keep the other fields
- To add a new field
Show answer
To keep the other fields — ...form keeps the fields that are not updated.
Next lesson: Validation