Managing Input Fields Using TextInput in React Native
Course: React Native Training
Topic: Managing Input Fields Using TextInput
Course Link: React Native Training at JustAcademy
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction to TextInput in React Native
TextInput is a core React Native component that allows users to enter and edit text using the device keyboard. It is commonly used to build login screens, registration forms, search boxes, contact forms, feedback forms, messaging applications, and other interactive mobile interfaces.
React Native provides properties and event handlers that help developers control the entered text, choose suitable keyboard layouts, validate user input, handle focus, submit forms, and improve the overall user experience.
1.1 What Is TextInput?
TextInput is a component that receives text from users and allows the application to respond to changes in that text. It supports single-line and multiline input, placeholders, secure password entry, keyboard configuration, and several input events.
1.2 Why Is TextInput Important?
- Collects information directly from users.
- Supports login and registration workflows.
- Allows users to search for content.
- Accepts email addresses, phone numbers, names, passwords, and messages.
- Provides events for responding to typing, focus changes, and submission.
- Supports input validation and error messages.
- Helps build reusable and accessible form components.
1.3 Common Applications
| Application |
Example |
Purpose |
| Login screen |
Email and password |
Collects login credentials. |
| Registration form |
Name, email, phone |
Creates a user profile. |
| Search screen |
Search keyword |
Finds relevant content. |
| Messaging app |
Message text |
Composes messages. |
| Feedback form |
Comments |
Collects longer responses. |
| Profile screen |
Display name |
Updates user information. |
2. Learning Objectives
After completing this topic, learners should be able to:
- Understand the purpose and working of React Native's TextInput component.
- Create controlled input fields using React state.
- Handle user input with the onChangeText event.
- Configure keyboard types, placeholders, and capitalization.
- Build password and multiline text fields.
- Validate user input and display error messages.
- Handle focus, blur, and form submission events.
- Manage multiple input fields in a form.
- Improve usability, accessibility, and security.
- Build a functional form using reusable input components.
3. Setting Up TextInput
3.1 Importing TextInput
To use TextInput, import it from the react-native package along with the other components needed by your screen.
import React, { useState } from 'react';
import {
View,
Text,
TextInput,
StyleSheet
} from 'react-native';
3.2 Creating a Basic Input Field
The following example creates a simple field that accepts a user's name.
import React, { useState } from 'react';
import { View, Text, TextInput } from 'react-native';
export default function NameInput() {
const [name, setName] = useState('');
return (
<View>
<Text>Enter your name</Text>
<TextInput
placeholder="Your name"
value={name}
onChangeText={setName}
/>
<Text>Entered name: {name}</Text>
</View>
);
}
Explanation:
useState('') creates state for the entered name.
placeholder displays a hint when the field is empty.
value={name} connects the displayed text to state.
onChangeText={setName} updates state whenever the user types.
- The final Text component displays the current value.
3.3 Styling the Input Field
TextInput can be styled using React Native's style prop. Common styling properties include height, padding, border width, border color, font size, and border radius.
const styles = StyleSheet.create({
input: {
height: 48,
borderWidth: 1,
borderColor: '#999999',
borderRadius: 8,
paddingHorizontal: 12,
fontSize: 16,
marginVertical: 8
}
});
Apply the style using style={styles.input} on the TextInput component. React Native styles use JavaScript objects rather than CSS files.
4. Understanding Controlled and Uncontrolled Inputs
4.1 Controlled Input
A controlled input receives its value from React state. The value prop determines the displayed text, and onChangeText updates that state.
const [email, setEmail] = useState('');
<TextInput
value={email}
onChangeText={setEmail}
placeholder="Enter email"
/>
Advantages:
- Provides predictable input behavior.
- Makes validation easier.
- Allows values to be cleared or changed programmatically.
- Supports conditional UI and form submission.
- Makes it straightforward to manage multiple fields.
4.2 Uncontrolled Input
An uncontrolled input can use defaultValue to specify its initial text without keeping every change synchronized with a state variable.
<TextInput
defaultValue="Welcome"
placeholder="Enter text"
/>
This approach may be useful for simple fields that do not need to be read or validated continuously. If an application needs reliable access to the latest input, controlled state is generally easier to manage.
4.3 Controlled vs. Uncontrolled Inputs
| Feature |
Controlled |
Uncontrolled |
| Value management |
Managed using React state |
Primarily managed by the input component |
| Initial value |
Usually provided through value |
Usually provided through defaultValue |
| Validation |
Easy to coordinate with state |
Requires a suitable way to access the current value |
| Programmatic updates |
Straightforward through state |
Less direct |
| Typical use |
Forms, login screens, search interfaces |
Simple fields that need little application control |
5. Managing Input with useState
5.1 Introduction to useState
The useState Hook stores information that changes during a component's lifetime. When a state value changes, React renders the component again so that the UI reflects the updated value.
const [username, setUsername] = useState('');
Here, username contains the current value, while setUsername updates it.
5.2 Updating Input State
function UsernameField() {
const [username, setUsername] = useState('');
return (
<TextInput
value={username}
onChangeText={(text) => setUsername(text)}
placeholder="Username"
/>
);
}
The onChangeText callback receives the updated text as a string. It does not require extracting the text from a browser-style event object.
5.3 Clearing an Input Field
function ClearableInput() {
const [text, setText] = useState('');
return (
<View>
<TextInput
value={text}
onChangeText={setText}
placeholder="Type something"
/>
<Text onPress={() => setText('')}>
Clear input
</Text>
</View>
);
}
This example demonstrates state-based clearing. In a production interface, use a button component for the clear action and give it a clear accessible label.
6. Important TextInput Props
Props control how a field looks, accepts text, interacts with the keyboard, and responds to user actions.
| Prop |
Purpose |
Example |
| value |
Sets the current controlled value. |
value={email} |
| defaultValue |
Sets an initial value. |
defaultValue="Guest" |
| onChangeText |
Runs when the text changes. |
onChangeText={setEmail} |
| placeholder |
Shows a hint when the field is empty. |
placeholder="Enter email" |
| placeholderTextColor |
Changes the placeholder color. |
placeholderTextColor="#777" |
| keyboardType |
Chooses a suitable keyboard layout. |
keyboardType="email-address" |
| secureTextEntry |
Obscures sensitive text such as a password. |
secureTextEntry={true} |
| multiline |
Allows text to span multiple lines. |
multiline={true} |
| maxLength |
Limits the number of entered characters. |
maxLength={50} |
| autoCapitalize |
Controls automatic capitalization. |
autoCapitalize="none" |
| autoCorrect |
Controls text auto-correction. |
autoCorrect={false} |
| editable |
Controls whether text can be edited. |
editable={false} |
| autoFocus |
Requests focus when the component mounts. |
autoFocus={true} |
| returnKeyType |
Customizes the keyboard's return key. |
returnKeyType="done" |
| onSubmitEditing |
Handles the keyboard submission action. |
onSubmitEditing={handleSubmit} |
| onFocus |
Runs when the field receives focus. |
onFocus={handleFocus} |
| onBlur |
Runs when the field loses focus. |
onBlur={handleBlur} |
7. Choosing the Correct Keyboard Type
The keyboardType prop helps display a keyboard that suits the expected data. Choosing an appropriate keyboard reduces unnecessary typing and improves usability.
| Keyboard Type |
Recommended Use |
default |
General text input. |
email-address |
Email addresses. |
numeric |
Numeric input. |
number-pad |
Number entry on supported platforms. |
decimal-pad |
Numbers containing decimal values. |
phone-pad |
Telephone numbers. |
url |
Website addresses. |
search |
Search terms. |
7.1 Example: Email Input
<TextInput
value={email}
onChangeText={setEmail}
placeholder="[email protected]"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>
7.2 Example: Phone Number Input
<TextInput
value={phone}
onChangeText={setPhone}
placeholder="Enter phone number"
keyboardType="phone-pad"
maxLength={15}
/>
A keyboard type only influences the keyboard layout. It does not guarantee that the entered value is valid. Validate phone numbers, numeric values, and other structured input separately.
8. Creating Password Fields
Password fields are used on login, registration, and password-reset screens. The secureTextEntry prop obscures the text entered into a single-line field.
function PasswordInput() {
const [password, setPassword] = useState('');
return (
<TextInput
value={password}
onChangeText={setPassword}
placeholder="Enter password"
secureTextEntry={true}
autoCapitalize="none"
autoCorrect={false}
/>
);
}
8.1 Password Field Best Practices
- Use secure text entry when appropriate.
- Do not print passwords in logs or error messages.
- Do not store passwords in ordinary persistent storage unnecessarily.
- Validate password requirements without exposing the password.
- Use HTTPS when sending credentials to a server.
- Keep password handling separate from presentation logic when building larger forms.
- Consider a clearly labeled show/hide password control if the design requires it.
Obscuring text is a display feature, not a complete security solution. Authentication, secure network communication, and credential storage require additional safeguards.
9. Handling Multiline Input
Use multiline={true} when the user needs to enter longer text, such as a message, description, review, or feedback comment.
function FeedbackInput() {
const [feedback, setFeedback] = useState('');
return (
<View>
<Text>Your feedback</Text>
<TextInput
value={feedback}
onChangeText={setFeedback}
placeholder="Write your feedback here"
multiline={true}
numberOfLines={4}
maxLength={500}
textAlignVertical="top"
style={{
minHeight: 120,
borderWidth: 1,
borderColor: '#999',
borderRadius: 8,
padding: 12
}}
/>
<Text>{feedback.length}/500 characters</Text>
</View>
);
}
9.1 Important Multiline Considerations
- Use
multiline={true} to allow line breaks.
- Use
textAlignVertical="top" for consistent top alignment where supported.
- Use a suitable minimum height and padding.
- Set a reasonable character limit when required.
- Test the field on both Android and iOS.
- Do not assume
numberOfLines behaves identically across all platforms and React Native versions.
10. Handling TextInput Events
10.1 onChangeText
onChangeText is one of the most frequently used TextInput props. It receives the new text value whenever the input changes.
<TextInput
value={name}
onChangeText={(text) => setName(text)}
placeholder="Enter your name"
/>
10.2 onFocus
The onFocus event runs when the user selects or focuses the field. It can be used to highlight the field or update interface state.
<TextInput
value={name}
onChangeText={setName}
onFocus={() => console.log('Input focused')}
/>
10.3 onBlur
The onBlur event runs when the field loses focus. It is useful for checking whether an entered value meets basic requirements after the user leaves the field.
<TextInput
value={email}
onChangeText={setEmail}
onBlur={() => setEmailTouched(true)}
/>
10.4 onSubmitEditing
onSubmitEditing runs when the user activates the keyboard's submission key, subject to platform and keyboard behavior. It can submit a search query or move a form toward its next action.
<TextInput
value={search}
onChangeText={setSearch}
placeholder="Search"
returnKeyType="search"
onSubmitEditing={() => performSearch(search)}
/>
Ensure that performSearch is defined in the component. For phone-pad keyboards, some submission events may behave differently across platforms.
10.5 Event Summary
| Event |
When It Runs |
Typical Use |
| onChangeText |
Text changes. |
Update state and live feedback. |
| onFocus |
Field receives focus. |
Highlight active input. |
| onBlur |
Field loses focus. |
Trigger field-level validation. |
| onEndEditing |
Editing ends. |
Process the final edited value. |
| onSubmitEditing |
Keyboard submission action occurs. |
Submit a search or form. |
| onKeyPress |
A supported keyboard key is pressed. |
Special key interactions. |
| onSelectionChange |
Text selection changes. |
Respond to cursor or selection changes. |
11. Managing Multiple Input Fields
Forms commonly contain several inputs, including a name, email address, phone number, and password. Each field needs a value and a way to update it.
11.1 Separate State Variables
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
<TextInput value={name} onChangeText={setName} placeholder="Name" />
<TextInput value={email} onChangeText={setEmail} placeholder="Email" />
<TextInput value={phone} onChangeText={setPhone} placeholder="Phone" />
This method is easy to understand and works well for small forms.
11.2 Grouping Form State in an Object
For a form with several fields, an object can keep related values together.
const [form, setForm] = useState({
name: '',
email: '',
phone: ''
});
function updateField(field, value) {
setForm(previous => ({
...previous,
[field]: value
}));
}
// Example fields
<TextInput
value={form.name}
onChangeText={(value) => updateField('name', value)}
placeholder="Full name"
/>
<TextInput
value={form.email}
onChangeText={(value) => updateField('email', value)}
placeholder="Email address"
keyboardType="email-address"
autoCapitalize="none"
/>
The spread operator preserves the other fields while updating only the selected property. This prevents a change to one field from accidentally removing the other form values.
12. Input Validation
Input validation checks whether the data entered by a user meets the application's requirements. Validation can occur while the user types, when the field loses focus, or when the user submits the form.
12.1 Why Validation Is Necessary
- Prevents empty required fields from being submitted.
- Helps identify incorrectly formatted email addresses.
- Enforces character limits and other field requirements.
- Provides useful feedback before a request is sent to the server.
- Improves the reliability of information collected by the application.
12.2 Required Field Validation
const [name, setName] = useState('');
const [submitted, setSubmitted] = useState(false);
const nameError =
submitted && name.trim().length === 0
? 'Name is required.'
: '';
function handleSubmit() {
setSubmitted(true);
if (!name.trim()) {
return;
}
// Continue with the valid form data.
}
12.3 Email Validation
function isValidEmail(value) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
}
const emailError =
submitted && !isValidEmail(email)
? 'Enter a valid email address.'
: '';
This regular expression provides a basic format check. It does not prove that an email address exists or that the user owns it. Important data should also be validated by the server.
12.4 Displaying Validation Errors
<TextInput
value={email}
onChangeText={setEmail}
placeholder="Email address"
keyboardType="email-address"
autoCapitalize="none"
accessibilityLabel="Email address"
/>
{emailError ? (
<Text accessibilityLiveRegion="polite">
{emailError}
</Text>
) : null}
Keep error messages clear, associate them with the correct field, and avoid showing errors before the user has had a reasonable opportunity to enter data.
13. Building a Complete Registration Form
The following example combines several important concepts: controlled input fields, keyboard configuration, basic validation, character handling, and form submission.
import React, { useState } from 'react';
import {
View,
Text,
TextInput,
Pressable,
StyleSheet
} from 'react-native';
export default function RegistrationForm() {
const [form, setForm] = useState({
name: '',
email: '',
password: ''
});
const [submitted, setSubmitted] = useState(false);
const [successMessage, setSuccessMessage] = useState('');
function updateField(field, value) {
setForm(previous => ({
...previous,
[field]: value
}));
setSuccessMessage('');
}
const nameError =
submitted && !form.name.trim()
? 'Please enter your name.'
: '';
const emailError =
submitted && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim())
? 'Please enter a valid email address.'
: '';
const passwordError =
submitted && form.password.length < 8
? 'Password must contain at least 8 characters.'
: '';
function handleSubmit() {
setSubmitted(true);
setSuccessMessage('');
const validName = form.name.trim().length > 0;
const validEmail =
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
const validPassword = form.password.length >= 8;
if (!validName || !validEmail || !validPassword) {
return;
}
// Send form data to your backend here.
// Never log the password or expose it in UI messages.
setSuccessMessage('Form validation completed successfully.');
}
return (
<View style={styles.container}>
<Text style={styles.title}>Create Account</Text>
<Text style={styles.label}>Full Name</Text>
<TextInput
style={styles.input}
value={form.name}
onChangeText={(value) => updateField('name', value)}
placeholder="Enter your name"
autoCapitalize="words"
autoCorrect={false}
accessibilityLabel="Full name"
/>
{nameError ? <Text style={styles.error}>{nameError}</Text> : null}
<Text style={styles.label}>Email Address</Text>
<TextInput
style={styles.input}
value={form.email}
onChangeText={(value) => updateField('email', value)}
placeholder="Enter your email"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
accessibilityLabel="Email address"
/>
{emailError ? <Text style={styles.error}>{emailError}</Text> : null}
<Text style={styles.label}>Password</Text>
<TextInput
style={styles.input}
value={form.password}
onChangeText={(value) => updateField('password', value)}
placeholder="At least 8 characters"
secureTextEntry={true}
autoCapitalize="none"
autoCorrect={false}
accessibilityLabel="Password"
/>
{passwordError ? <Text style={styles.error}>{passwordError}</Text> : null}
<Pressable
style={styles.button}
onPress={handleSubmit}
accessibilityRole="button"
accessibilityLabel="Submit registration form"
>
<Text style={styles.buttonText}>Register</Text>
</Pressable>
{successMessage ? (
<Text accessibilityLiveRegion="polite">
{successMessage}
</Text>
) : null}
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 20
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20
},
label: {
fontSize: 16,
marginBottom: 6
},
input: {
minHeight: 48,
borderWidth: 1,
borderColor: '#999999',
borderRadius: 8,
paddingHorizontal: 12,
marginBottom: 8
},
error: {
marginBottom: 10
},
button: {
padding: 14,
borderRadius: 8,
alignItems: 'center',
marginTop: 12,
backgroundColor: '#2457C5'
},
buttonText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: 'bold'
}
});
13.1 How the Example Works
- The form state object stores the name, email, and password.
- The updateField function changes the selected field while preserving the remaining values.
- The name validator checks whether the name contains non-whitespace characters.
- The email validator performs a basic email-format check.
- The password validator checks for a minimum of eight characters.
- The submitted state controls when validation errors are displayed.
- The submit handler stops when the entered values are invalid.
- When basic validation succeeds, the example displays a message. A real registration flow must send the data to a backend and handle the response.
14. Managing Focus and Keyboard Behavior
14.1 What Is Focus?
A field has focus when it is active and ready to receive text. Focus management is helpful when moving between form fields or directing the user to a field that needs attention.
14.2 Focusing an Input Programmatically
React Native exposes methods such as focus() and blur() on the TextInput instance. A ref can be used to call these methods.
import React, { useRef, useState } from 'react';
import { View, TextInput, Button } from 'react-native';
export default function FocusExample() {
const inputRef = useRef(null);
const [text, setText] = useState('');
return (
<View>
<TextInput
ref={inputRef}
value={text}
onChangeText={setText}
placeholder="Enter text"
/>
<Button
title="Focus input"
onPress={() => inputRef.current?.focus()}
/>
<Button
title="Dismiss focus"
onPress={() => inputRef.current?.blur()}
/>
</View>
);
}
14.3 Keyboard Configuration
- Use
returnKeyType="next" when the user should move to another field.
- Use
returnKeyType="done" for an appropriate final input action.
- Use
onSubmitEditing to handle keyboard submission.
- Use
autoFocus only when immediately focusing the field improves the experience.
- Test how the keyboard affects the screen on small devices.
15. Reusable TextInput Components
In larger applications, creating a reusable input component reduces duplicated code and encourages consistent styling, labels, validation messages, and accessibility properties.
15.1 Creating a Reusable Input Component
import React from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';
export default function FormInput({
label,
value,
onChangeText,
placeholder,
error,
keyboardType = 'default',
secureTextEntry = false
}) {
return (
<View style={styles.wrapper}>
<Text style={styles.label}>{label}</Text>
<TextInput
style={styles.input}
value={value}
onChangeText={onChangeText}
placeholder={placeholder}
keyboardType={keyboardType}
secureTextEntry={secureTextEntry}
autoCapitalize={keyboardType === 'email-address' ? 'none' : 'sentences'}
accessibilityLabel={label}
/>
{error ? <Text style={styles.error}>{error}</Text> : null}
</View>
);
}
const styles = StyleSheet.create({
wrapper: {
marginBottom: 16
},
label: {
fontSize: 15,
marginBottom: 6
},
input: {
minHeight: 48,
borderWidth: 1,
borderColor: '#999999',
borderRadius: 8,
paddingHorizontal: 12
},
error: {
marginTop: 4
}
});
15.2 Using the Reusable Component
<FormInput
label="Email Address"
value={email}
onChangeText={setEmail}
placeholder="[email protected]"
keyboardType="email-address"
error={emailError}
/>
<FormInput
label="Password"
value={password}
onChangeText={setPassword}
placeholder="Enter password"
secureTextEntry={true}
error={passwordError}
/>
Reusable components can also accept props for maximum length, multiline input, helper text, disabled states, test identifiers, and custom validation rules. For a production component, consider whether capitalization should be configurable rather than inferred from keyboard type.
16. Styling and Improving Input Usability
16.1 Basic Styling Properties
| Property |
Purpose |
| height / minHeight |
Controls the field's vertical size. |
| paddingHorizontal |
Adds horizontal space inside the field. |
| fontSize |
Controls text size. |
| borderWidth |
Sets border thickness. |
| borderColor |
Sets border color. |
| borderRadius |
Rounds the field's corners. |
| color |
Sets the entered text color. |
| backgroundColor |
Sets the field's background color. |
| marginBottom |
Adds space below the field. |
16.2 Focused and Error States
A form can use state to indicate when a field is focused or invalid. For example, change the border color when the input receives focus and display a separate message when validation fails.
const [isFocused, setIsFocused] = useState(false);
<TextInput
value={email}
onChangeText={setEmail}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
style={{
borderWidth: 1,
borderColor: isFocused ? '#2457C5' : '#999999',
borderRadius: 8,
padding: 12
}}
/>
16.3 Usability Recommendations
- Use a clear label for each input.
- Use placeholders as hints, not as the only label.
- Keep touch targets and input heights comfortable on mobile devices.
- Use a suitable keyboard for each kind of information.
- Provide readable error messages close to the affected field.
- Ensure adequate contrast between text, placeholders, borders, and backgrounds.
- Support device text scaling where practical.
- Test long input, pasted text, and small-screen layouts.
17. Handling Search Input
A search field is a common use of TextInput. It stores the query and lets the application run a search when the user submits it.
function SearchBox({ onSearch }) {
const [query, setQuery] = useState('');
function submitSearch() {
const cleanedQuery = query.trim();
if (cleanedQuery.length > 0) {
onSearch(cleanedQuery);
}
}
return (
<TextInput
value={query}
onChangeText={setQuery}
placeholder="Search items"
returnKeyType="search"
onSubmitEditing={submitSearch}
autoCapitalize="none"
autoCorrect={false}
accessibilityLabel="Search items"
/>
);
}
The parent component supplies the onSearch function. In a larger application, consider debouncing live search requests so the app does not send a network request for every keystroke.
18. Accessibility Best Practices
Accessible input fields help users understand the purpose of each field and interact with forms using different assistive technologies.
- Provide a meaningful visible label and an appropriate
accessibilityLabel.
- Ensure text and placeholder colors have sufficient contrast.
- Do not rely on color alone to communicate validation errors.
- Use clear error messages and identify the field that needs correction.
- Ensure controls can be reached and used with supported assistive technologies.
- Use meaningful button labels for actions such as clearing a field or submitting a form.
- Test with VoiceOver on iOS and TalkBack on Android.
- Check that larger system text settings do not make important content inaccessible.
19. Common Errors and Troubleshooting
| Problem |
Possible Cause |
Solution |
| Input does not update |
State is not updated in onChangeText. |
Connect onChangeText to the correct state setter. |
| Text disappears while typing |
The controlled value is being reset. |
Check state updates and ensure value remains a string. |
| Keyboard shows the wrong layout |
Incorrect keyboardType or inputMode. |
Choose the most suitable supported keyboard option. |
| Password is visible |
secureTextEntry is missing or false. |
Set secureTextEntry to true for a single-line password field. |
| Field accepts too many characters |
No character limit has been set. |
Use maxLength and validate important constraints separately. |
| Validation error appears too early |
Validation runs before the user has interacted with the field. |
Track touched or submitted state. |
| Form submits empty values |
Submission logic does not validate the data. |
Validate required fields before continuing. |
| Keyboard hides the form button |
Screen layout does not respond well to the keyboard. |
Review scrolling, keyboard avoidance, and screen layout behavior. |
| Multiline text is vertically centered |
Platform-specific text alignment behavior. |
Try textAlignVertical="top" and test both platforms. |
| Autofill behaves unexpectedly |
Autocomplete hints or platform support differ. |
Review autoComplete and test on supported devices. |
19.1 Keeping Controlled Values as Strings
For controlled TextInput fields, initialize text state with an empty string rather than null or undefined. When data comes from an API, convert optional values to a string before passing them to the input.
const [phone, setPhone] = useState('');
<TextInput
value={phone}
onChangeText={setPhone}
keyboardType="phone-pad"
/>
19.2 Handling the Keyboard and Screen Layout
On smaller devices, the software keyboard can cover fields or buttons. Depending on the screen, consider a scrollable layout, suitable safe-area handling, or React Native's KeyboardAvoidingView. Test on real Android and iOS devices because keyboard behavior can differ.
20. Performance and Form Management Best Practices
- Keep state close to the component that needs it.
- Use controlled inputs where the application needs validation or programmatic updates.
- Avoid expensive calculations on every keystroke.
- Debounce frequent search requests when appropriate.
- Extract repeated input markup into reusable components.
- Use functional state updates when the new value depends on previous state.
- Validate important information on the server as well as in the interface.
- Keep API submission logic separate from the visual field components.
- Handle loading, success, and failure states when connecting a form to an API.
- Do not log sensitive input values such as passwords or authentication codes.
21. Practical Project: Contact Form
Project Objective
Create a contact form in React Native that collects a user's name, email address, and message. The application should validate the input and display a confirmation when the form passes basic validation.
Project Requirements
- Create three controlled TextInput fields.
- Use an email keyboard for the email field.
- Use multiline input for the message.
- Limit the message length to a reasonable number of characters.
- Validate required fields.
- Display relevant error messages.
- Handle submission using a button.
- Display a success message only after validation passes.
- Use consistent input styling and accessible labels.
Suggested Implementation Steps
- Create a new React Native screen component.
- Import View, Text, TextInput, Pressable, and useState.
- Create state variables for name, email, message, and submission status.
- Add controlled fields using value and onChangeText.
- Implement required-field and email-format validation.
- Write a submit handler that prevents invalid submission.
- Add clear error messages and success feedback.
- Test keyboard behavior, validation, and layout on Android and iOS.
Expected Outcome
The completed form should accept user input, keep the values synchronized with React state, display useful validation messages, and provide clear feedback after a valid submission. Sending the contact details to a real service requires an additional backend or API integration.
22. Practice Exercises
- Create a TextInput that accepts a user's full name.
- Build an email field using keyboardType and autoCapitalize correctly.
- Create a password field using secureTextEntry.
- Build a multiline feedback field with a character counter.
- Create a form containing name, email, and phone fields.
- Show a required-field error after a user attempts to submit an empty form.
- Build a search field that submits a non-empty query.
- Use a ref to focus an input when a button is pressed.
- Create a reusable FormInput component that supports labels and errors.
- Build a registration form and test its behavior on Android and iOS.
23. Interview Questions and Answers
Q1. What is TextInput in React Native?
Answer: TextInput is a core component that allows users to enter and edit text using the device keyboard.
Q2. What is the purpose of onChangeText?
Answer: It is a callback that receives the new text value whenever the content of a TextInput changes.
Q3. What is a controlled input?
Answer: A controlled input uses React state as its source of truth through the value prop. The state is updated through a handler such as onChangeText.
Q4. What is the difference between value and defaultValue?
Answer: The value prop controls the current displayed text, while defaultValue specifies the initial text for an input that is not being controlled through value.
Q5. How do you create a password input?
Answer: Use TextInput with secureTextEntry set to true. Additional authentication and data-protection measures are still necessary.
Q6. How can you select the email keyboard?
Answer: Set keyboardType to email-address. For many email fields, autoCapitalize="none" and autoCorrect={false} are also appropriate.
Q7. How do you create a multiline field?
Answer: Set multiline to true and provide suitable height, padding, and alignment. Test its behavior across platforms.
Q8. How can you limit the number of characters?
Answer: Use the maxLength prop. Additional validation may still be needed for application-specific rules.
Q9. What is the purpose of onFocus and onBlur?
Answer: onFocus runs when the field receives focus, while onBlur runs when it loses focus. They can be used for focus styling and validation timing.
Q10. What is onSubmitEditing used for?
Answer: It handles the keyboard submission action, such as submitting a search query. Its behavior can depend on the keyboard and platform.
Q11. Why should forms validate input?
Answer: Validation helps identify missing or incorrectly formatted information before continuing with an operation. The server should also validate important data.
Q12. How can several fields be managed together?
Answer: Use separate state variables or store the field values in an object and update one property at a time while preserving the other properties.
Q13. How can a TextInput be focused programmatically?
Answer: Create a ref using useRef, assign it to the TextInput, and call the focus method when appropriate.
Q14. Why is a placeholder not a complete replacement for a label?
Answer: Placeholder text disappears when users type and may be less accessible. A visible label makes the field's purpose clear throughout interaction.
Q15. What should be considered when using TextInput across Android and iOS?
Answer: Test keyboard behavior, text alignment, autofill, focus handling, and screen layout on both platforms because some properties and behaviors differ.
24. Quick Revision Checklist
- TextInput collects and edits text entered by the user.
- Import TextInput from the react-native package.
- Use useState to manage controlled input values.
- Use value and onChangeText together for controlled fields.
- Use placeholder to provide a short hint.
- Choose a suitable keyboardType for the expected data.
- Use secureTextEntry for password-style display.
- Use multiline for longer text.
- Use maxLength to restrict the number of entered characters.
- Use onFocus, onBlur, and onSubmitEditing for interaction handling.
- Validate input before allowing form submission.
- Keep controlled text values as strings.
- Use reusable components to maintain consistent form design.
- Provide accessible labels and useful error messages.
- Test forms on Android and iOS.
- Validate important data on the server and protect sensitive information.
25. Conclusion
Managing input fields using TextInput is an essential React Native skill. It enables developers to collect user information, create interactive forms, manage text through state, configure keyboards, handle focus and submission events, and validate information before processing it.
By combining controlled inputs, appropriate keyboard settings, accessible labels, reusable components, clear validation messages, and secure handling of sensitive information, developers can create reliable mobile forms. Practice these concepts by building registration, login, search, and contact screens, and test each form on both Android and iOS.
26. Additional Learning Resources