Chapter 15: Expo React Native Handling Form Input
Handling form input is a critical part of developing interactive applications. In React Native, handling form input involves managing state, validating inputs, and ensuring the data is processed correctly. This chapter focuses on creating robust forms using controlled and uncontrolled components, validating form inputs with Formik, and schema validation with Yup.
1. Introduction to Forms in React Native
Forms in React Native allow users to input and submit data, similar to web forms. However, since React Native is a mobile framework, there are some differences in handling input fields, especially when it comes to managing keyboard interactions, input validation, and navigation between input fields.
Key Points:
- Form Components: React Native provides various form components like
TextInput,Picker,Switch,CheckBox, etc. - Handling State: Form input is usually controlled using React state management to keep track of the input values.
Example: Basic Form in React Native
import React, { useState } from "react";
import { View, TextInput, Button, Text, StyleSheet } from "react-native";
export default function BasicForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [submitted, setSubmitted] = useState(false);
const handleSubmit = () => {
setSubmitted(true);
};
return (
<View style={styles.container}>
<Text style={styles.label}>Name:</Text>
<TextInput
style={styles.input}
placeholder="Enter your name"
value={name}
onChangeText={setName}
/>
<Text style={styles.label}>Email:</Text>
<TextInput
style={styles.input}
placeholder="Enter your email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
/>
<Button title="Submit" onPress={handleSubmit} />
{submitted && (
<Text style={styles.message}>
Form Submitted! Name: {name}, Email: {email}
</Text>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
label: {
fontSize: 18,
marginVertical: 10,
},
input: {
borderColor: "#ccc",
borderWidth: 1,
padding: 10,
marginBottom: 20,
},
message: {
marginTop: 20,
fontSize: 16,
color: "green",
},
});
Explanation:
TextInputcomponents are controlled using state variables (nameandemail).- The
handleSubmitfunction is called when the "Submit" button is pressed, setting thesubmittedstate totrue.
2. Using Controlled and Uncontrolled Components
React Native forms can be built using controlled or uncontrolled components:
- Controlled Components: The input value is controlled by React state, which provides a single source of truth. Changes in input are managed via
onChangehandlers, making it easier to validate and manipulate the form data. - Uncontrolled Components: The input value is not controlled by React state. Instead, refs are used to access the input values. This method is less common in React Native but useful in certain scenarios where direct DOM access is needed.
Example: Controlled vs. Uncontrolled Components
import React, { useState, useRef } from "react";
import { View, TextInput, Button, Text, StyleSheet } from "react-native";
export default function ControlledUncontrolledForm() {
const [controlledInput, setControlledInput] = useState("");
const uncontrolledInputRef = useRef(null);
const handleSubmit = () => {
console.log("Controlled Input:", controlledInput);
console.log("Uncontrolled Input:", uncontrolledInputRef.current.value);
};
return (
<View style={styles.container}>
<Text style={styles.label}>Controlled Input:</Text>
<TextInput
style={styles.input}
value={controlledInput}
onChangeText={setControlledInput}
/>
<Text style={styles.label}>Uncontrolled Input:</Text>
<TextInput style={styles.input} ref={uncontrolledInputRef} />
<Button title="Submit" onPress={handleSubmit} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
label: {
fontSize: 18,
marginVertical: 10,
},
input: {
borderColor: "#ccc",
borderWidth: 1,
padding: 10,
marginBottom: 20,
},
});
Explanation:
- The
controlledInputstate variable is updated throughonChangeText. uncontrolledInputRefis used to access the value of the uncontrolled input.
3. Validating Input with Formik
Formik is a popular library for managing form state and handling form validation in React and React Native applications. It simplifies form management by providing a set of components and hooks to handle form state, validation, and submission.
Key Points:
- Formik Setup: Formik provides a
Formikcomponent or a hook (useFormik) to manage form state and validation. - Validation: You can validate form fields using synchronous or asynchronous functions.
Example: Basic Form with Formik
import React from "react";
import { View, TextInput, Button, Text, StyleSheet } from "react-native";
import { Formik } from "formik";
export default function FormikForm() {
return (
<Formik
initialValues={{ name: "", email: "" }}
onSubmit={(values) => console.log(values)}
validate={(values) => {
const errors = {};
if (!values.name) {
errors.name = "Required";
}
if (!values.email) {
errors.email = "Required";
} else if (!/\S+@\S+\.\S+/.test(values.email)) {
errors.email = "Invalid email address";
}
return errors;
}}
>
{({ handleChange, handleBlur, handleSubmit, values, errors }) => (
<View style={styles.container}>
<Text style={styles.label}>Name:</Text>
<TextInput
style={styles.input}
onChangeText={handleChange("name")}
onBlur={handleBlur("name")}
value={values.name}
/>
{errors.name && <Text style={styles.error}>{errors.name}</Text>}
<Text style={styles.label}>Email:</Text>
<TextInput
style={styles.input}
onChangeText={handleChange("email")}
onBlur={handleBlur("email")}
value={values.email}
keyboardType="email-address"
/>
{errors.email && <Text style={styles.error}>{errors.email}</Text>}
<Button title="Submit" onPress={handleSubmit} />
</View>
)}
</Formik>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
label: {
fontSize: 18,
marginVertical: 10,
},
input: {
borderColor: "#ccc",
borderWidth: 1,
padding: 10,
marginBottom: 20,
},
error: {
color: "red",
},
});
Explanation:
- Formik manages form state (
values), validation errors (errors), and handlers for changing input values (handleChange) and form submission (handleSubmit). - The
validatefunction synchronously checks the inputs and returns any errors.
4. Schema Validation with Yup
Yup is a JavaScript schema builder for runtime value parsing and validation. It integrates well with Formik to handle complex form validation logic through a schema-based approach.
Key Points:
- Yup Setup: Yup allows you to define validation schemas for form inputs, making validation logic reusable and declarative.
- Integration with Formik: Formik can use a Yup schema to validate form fields automatically.
Example: Formik with Yup Validation
import React from "react";
import { View, TextInput, Button, Text, StyleSheet } from "react-native";
import { Formik } from "formik";
import * as Yup from "yup";
// Define validation schema with Yup
const validationSchema = Yup.object().shape({
name: Yup.string().required("Name is required"),
email: Yup.string()
.email("Invalid email address")
.required("Email is required"),
});
export default function FormikYupForm() {
return (
<Formik
initialValues={{ name: "", email: "" }}
onSubmit={(values) => console.log(values)}
validationSchema={validationSchema} // Use Yup schema for validation
>
{({
handleChange,
handleBlur,
handleSubmit,
values,
errors,
touched,
}) => (
<View style={styles.container}>
<Text style={styles.label}>Name:</Text>
<TextInput
style={styles.input}
onChangeText={handleChange("name")}
onBlur={handleBlur("name")}
value={values.name}
/>
{errors.name && touched.name && (
<Text style={styles.error}>{errors.name}</Text>
)}
<Text style={styles.label}>Email:</Text>
<TextInput
style={styles.input}
onChange
Text={handleChange("email")}
onBlur={handleBlur("email")}
value={values.email}
keyboardType="email-address"
/>
{errors.email && touched.email && (
<Text style={styles.error}>{errors.email}</Text>
)}
<Button title="Submit" onPress={handleSubmit} />
</View>
)}
</Formik>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
label: {
fontSize: 18,
marginVertical: 10,
},
input: {
borderColor: "#ccc",
borderWidth: 1,
padding: 10,
marginBottom: 20,
},
error: {
color: "red",
},
});
Explanation:
- A Yup schema (
validationSchema) defines the rules for the form fields. - Formik's
validationSchemaprop is used to apply the Yup schema for validation. - The schema provides a clean, reusable way to manage complex validation logic.
By the end of this chapter, you should be comfortable with handling form inputs in React Native using both controlled and uncontrolled components, performing validation using Formik, and leveraging Yup for schema-based validation. This foundational knowledge will help you build dynamic and user-friendly forms in your Expo React Native applications.