Master React Native TextInput - Complete Guide

Last update: 2025-04-24
Type
Quick Win's logo Quick Win
Membership
🆓
Tech
TypeScript TypeScript
TypeScript
Share:

The TextInput component is a fundamental building block for collecting user input in React Native applications. Whether you’re building forms, search bars, or chat interfaces, understanding TextInput is crucial. In this guide, you’ll learn how to implement and customize TextInput with practical examples.

Basic TextInput Usage

Let’s start with a simple example:

import React, { useState } from 'react';
import { View, TextInput, StyleSheet } from 'react-native';

const BasicTextInput = () => {
	const [text, setText] = useState('');

	return (
		<View style={styles.container}>
			<TextInput
				style={styles.input}
				onChangeText={setText}
				value={text}
				placeholder="Enter text here"
				placeholderTextColor="#666"
			/>
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		padding: 20
	},
	input: {
		height: 40,
		borderWidth: 1,
		borderColor: '#ddd',
		borderRadius: 8,
		paddingHorizontal: 10,
		backgroundColor: '#fff'
	}
});

export default BasicTextInput;

This example demonstrates:

  • Basic input field setup with state management
  • Simple styling with borders and padding
  • Placeholder text with custom color
  • Controlled component pattern with value and onChangeText

Input Types and Keyboard Configuration

TextInput can be configured for different types of input:

import React, { useState } from 'react';
import { View, TextInput, StyleSheet } from 'react-native';

const InputTypes = () => {
	const [email, setEmail] = useState('');
	const [password, setPassword] = useState('');
	const [phone, setPhone] = useState('');

	return (
		<View style={styles.container}>
			<TextInput
				style={styles.input}
				onChangeText={setEmail}
				value={email}
				placeholder="Email"
				keyboardType="email-address"
				autoCapitalize="none"
				autoComplete="email"
			/>

			<TextInput
				style={styles.input}
				onChangeText={setPassword}
				value={password}
				placeholder="Password"
				secureTextEntry
				autoCapitalize="none"
			/>

			<TextInput
				style={styles.input}
				onChangeText={setPhone}
				value={phone}
				placeholder="Phone"
				keyboardType="phone-pad"
				autoComplete="tel"
			/>
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		padding: 20,
		gap: 10
	},
	input: {
		height: 40,
		borderWidth: 1,
		borderColor: '#ddd',
		borderRadius: 8,
		paddingHorizontal: 10,
		backgroundColor: '#fff'
	}
});

export default InputTypes;

Key features demonstrated:

  • Email input with appropriate keyboard type
  • Password input with secure text entry
  • Phone number input with numeric keyboard
  • Auto-capitalization and auto-complete settings

Advanced Styling and Validation

Here’s an example with more advanced styling and basic validation:

import React, { useState } from 'react';
import { View, TextInput, Text, StyleSheet } from 'react-native';

const AdvancedInput = () => {
	const [username, setUsername] = useState('');
	const [error, setError] = useState('');
	const [isFocused, setIsFocused] = useState(false);

	const validateUsername = (text: string) => {
		setUsername(text);
		if (text.length < 3) {
			setError('Username must be at least 3 characters');
		} else if (!/^[a-zA-Z0-9]+$/.test(text)) {
			setError('Username can only contain letters and numbers');
		} else {
			setError('');
		}
	};

	return (
		<View style={styles.container}>
			<Text style={styles.label}>Username</Text>
			<TextInput
				style={[styles.input, isFocused && styles.focused, error && styles.error]}
				onChangeText={validateUsername}
				value={username}
				placeholder="Enter username"
				onFocus={() => setIsFocused(true)}
				onBlur={() => setIsFocused(false)}
			/>
			{error ? <Text style={styles.errorText}>{error}</Text> : null}
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		padding: 20
	},
	label: {
		fontSize: 16,
		marginBottom: 8,
		color: '#333',
		fontWeight: '500'
	},
	input: {
		height: 40,
		borderWidth: 1,
		borderColor: '#ddd',
		borderRadius: 8,
		paddingHorizontal: 10,
		backgroundColor: '#fff'
	},
	focused: {
		borderColor: '#007AFF',
		shadowColor: '#007AFF',
		shadowOffset: { width: 0, height: 0 },
		shadowOpacity: 0.2,
		shadowRadius: 5
	},
	error: {
		borderColor: '#FF3B30'
	},
	errorText: {
		color: '#FF3B30',
		fontSize: 12,
		marginTop: 4
	}
});

export default AdvancedInput;

This example showcases:

  • Custom styling for focus and error states
  • Real-time input validation
  • Error message display
  • Shadow effects on focus
  • Input labels

Multiline Input and Character Count

For longer text input with character counting:

import React, { useState } from 'react';
import { View, TextInput, Text, StyleSheet } from 'react-native';

const MultilineInput = () => {
	const [text, setText] = useState('');
	const maxLength = 200;

	return (
		<View style={styles.container}>
			<TextInput
				style={styles.multilineInput}
				onChangeText={setText}
				value={text}
				placeholder="Write your message here..."
				multiline
				numberOfLines={4}
				maxLength={maxLength}
				textAlignVertical="top"
			/>
			<Text style={styles.counter}>
				{text.length}/{maxLength} characters
			</Text>
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		padding: 20
	},
	multilineInput: {
		height: 100,
		borderWidth: 1,
		borderColor: '#ddd',
		borderRadius: 8,
		paddingHorizontal: 10,
		paddingTop: 10,
		backgroundColor: '#fff',
		fontSize: 16
	},
	counter: {
		alignSelf: 'flex-end',
		color: '#666',
		fontSize: 12,
		marginTop: 4
	}
});

export default MultilineInput;

Features demonstrated:

  • Multiline input configuration
  • Character limit with counter
  • Proper text alignment for multiline input
  • Flexible height handling

Search Input with Clear Button

A common pattern for search functionality:

import React, { useState } from 'react';
import { View, TextInput, TouchableOpacity, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

const SearchInput = () => {
	const [search, setSearch] = useState('');

	const clearSearch = () => {
		setSearch('');
	};

	return (
		<View style={styles.container}>
			<View style={styles.searchContainer}>
				<Ionicons name="search" size={20} color="#666" style={styles.searchIcon} />
				<TextInput
					style={styles.searchInput}
					onChangeText={setSearch}
					value={search}
					placeholder="Search..."
					clearButtonMode="while-editing" // iOS only
				/>
				{search.length > 0 && (
					<TouchableOpacity onPress={clearSearch}>
						<Ionicons name="close-circle" size={20} color="#666" />
					</TouchableOpacity>
				)}
			</View>
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		padding: 20
	},
	searchContainer: {
		flexDirection: 'row',
		alignItems: 'center',
		backgroundColor: '#f0f0f0',
		borderRadius: 8,
		paddingHorizontal: 10
	},
	searchIcon: {
		marginRight: 10
	},
	searchInput: {
		flex: 1,
		height: 40,
		fontSize: 16
	}
});

export default SearchInput;

This search input demonstrates:

  • Icon integration with Expo vector icons
  • Clear button functionality
  • Platform-specific features (clearButtonMode for iOS)
  • Styled search container with icons

Best Practices

  1. Input Validation

    • Validate input in real-time when appropriate
    • Provide clear feedback for errors
    • Consider using a validation library for complex forms
  2. User Experience

    • Use appropriate keyboard types
    • Implement auto-capitalization rules
    • Add clear buttons for easy text clearing
    • Show/hide password toggles
  3. Performance

    • Debounce search input if making API calls
    • Use controlled components consistently
    • Handle keyboard events properly
  4. Styling

    • Maintain consistent styling across your app
    • Consider platform differences
    • Implement proper focus and error states
    • Use appropriate padding and spacing

Common Use Cases

  • Login/Registration forms
  • Search bars
  • Chat input fields
  • Comment sections
  • Profile editing
  • Settings forms

Summary

React Native’s TextInput component is versatile and can be customized for various use cases. By following these patterns and best practices, you can create polished and user-friendly input experiences in your apps.

Key takeaways:

  • Choose appropriate input types and keyboard configurations
  • Implement proper validation and error handling
  • Style inputs consistently with your app’s theme
  • Consider platform-specific features
  • Follow accessibility guidelines

Now you’re ready to implement professional text inputs in your React Native apps! 🚀

Zero to Hero React Native Mission
Simon Grimm