The TextInput component in React Native is the primary element for user text input, analogous to the HTML input element. TextInput supports controlled and uncontrolled state, various keyboard types, input masks, and focus event handling. According to React Native Docs, 2024, TextInput is a key component for forms, search, chats, and any user input scenarios. The component automatically adapts to the platform, using native UITextField on iOS and EditText on Android.
Key Takeaways
TextInput is a React Native component that allows users to enter text using the device keyboard. It is the main building block for registration forms, search bars, message input fields, and any other scenarios requiring user input. Unlike web development, where there are separate input types (text, email, password, search), in React Native all these variants are implemented through a single TextInput component with different props.
TextInput supports two modes of operation: controlled (managed through React state) and uncontrolled (using a ref). In controlled mode, the field value is stored in the component state and updated via the onChangeText callback. This approach is recommended for most applications as it provides a single source of truth and simplifies validation.
According to React Native Handling Text Input, 2024, TextInput automatically adapts to the platform: on iOS it uses native UITextField, on Android — EditText. This ensures proper operation of autocomplete, autocorrection, and system menus (cut/copy/paste) without additional configuration.
TextInput provides an extensive set of props for controlling input, appearance, and behavior. All props are divided into several categories: value management, keyboard type, styling, events, and platform-specific features.
value — the current field value (for controlled mode). onChangeText — callback invoked on every text change. placeholder — hint text displayed when the field is empty. defaultValue — initial value for uncontrolled mode. maxLength limits the maximum number of characters the user can enter.
The component supports onFocus (field received focus), onBlur (field lost focus), onSubmitEditing (user pressed Enter/Return), onKeyPress (key press). The onEndEditing event is called after editing ends when focus is lost. These callbacks allow implementing complex validation and form submission logic.
On iOS: clearButtonMode (clear button), keyboardAppearance (light/dark keyboard), returnKeyType (Return button type), enablesReturnKeyAutomatically. On Android: textContentType (autofill), underlineColorAndroid, inlineImageLeft. secureTextEntry works on both platforms for password input.
In React Native, TextInput can work in two modes. In controlled mode, React manages the field value: you pass value from state and update it via onChangeText. In uncontrolled mode, React only initializes the field, and the DOM-like value is stored inside the native component.
Controlled mode is recommended for all forms that require validation, filtering, or formatting of input data. The field state is synchronized with the React component state, giving full control over the value.
const LoginForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<View>
<TextInput
placeholder="Email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
<TextInput
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
maxLength={32}
/>
</View>
);
};
In this example, both fields use controlled mode. The email field has the email-address keyboard type and disabled auto-capitalization. The password field uses secureTextEntry to hide input characters and is limited to 32 characters via maxLength.
Uncontrolled mode is suitable for simple fields that do not require validation or immediate reaction to input. The field value is retrieved via a ref at form submission time.
const SimpleSearch = () => {
const inputRef = useRef(null);
const handleSearch = () => {
console.log(inputRef.current.value());
};
return (
<TextInput
ref={inputRef}
placeholder="Search..."
onSubmitEditing={handleSearch}
/>
);
};
In uncontrolled mode, the component renders faster as it does not require state synchronization on every text change. However, you lose the ability to filter, format, or validate input in real time.
TextInput supports various keyboard types that adapt the layout to the expected input format. Choosing the correct keyboard type improves user experience and reduces input errors on mobile devices.
| keyboardType Value | Description | When to Use |
|---|---|---|
| default | Standard alphabetic keyboard | First name, last name, address |
| numeric | Numeric keyboard (digits only) | Age, quantity, PIN code |
| email-address | Keyboard with @ and .com | Email field in registration form |
| phone-pad | Phone keyboard with + and # | Phone number |
| url | Keyboard with / and .com | Entering a web address |
| decimal-pad | Numeric keyboard with decimal point | Price, weight, size |
On iOS, additional types are available: numbers-and-punctuation, twitter, web-search (with voice search). On Android, visible-password is also available (shows password). Choosing the correct keyboardType is an important aspect of mobile application UX.
Platform features also include autoCapitalize (automatic capitalization of the first word), autoCorrect (autocorrection), spellCheck (spell checking), textContentType (autofill on iOS). These props work differently on each platform and require testing.
Let us consider two real-world scenarios: a multiline field for message input and a masked phone number input field. Both use TextInput with different props to achieve the desired behavior.
For entering long text (comments, descriptions), TextInput switches to multiline mode via the multiline prop. In this mode, the field grows vertically and supports line breaks.
const MessageInput = ({ onSend }) => {
const [text, setText] = useState('');
return (
<TextInput
style={styles.input}
multiline
numberOfLines={4}
placeholder="Write a message..."
value={text}
onChangeText={setText}
textAlignVertical="top"
/>
);
};
The multiline prop enables multiline mode, numberOfLines sets the initial height in lines. textAlignVertical: 'top' aligns text to the top (by default, Android multiline TextInput centers text vertically).
For entering a phone number, real-time formatting is often required. By combining onChangeText with regular expressions, you can implement an input mask.
const PhoneInput = () => {
const [phone, setPhone] = useState('');
const formatPhone = (text) => {
const cleaned = text.replace(/\D/g, '');
if (cleaned.length <= 11) {
return cleaned.replace(
/(\d{1})(\d{3})(\d{3})(\d{2})(\d{2})/,
'+$1 ($2) $3 $4 $5'
);
}
return cleaned;
};
return (
<TextInput
keyboardType="phone-pad"
value={phone}
onChangeText={(t) => setPhone(formatPhone(t))}
placeholder="+7 (999) 123 45 67"
maxLength={20}
/>
);
};
The formatPhone function removes all non-digit characters and formats the number into a standard international format. keyboardType: 'phone-pad' displays the phone keyboard. This approach improves UX for phone number input and prevents formatting errors.
Frequently Asked Questions
value is used in controlled mode — React manages the displayed text through state. defaultValue is used in uncontrolled mode — it sets the initial value, and subsequent changes are stored inside the component.
Set the secureTextEntry prop to true. TextInput will hide input characters, replacing them with dots or asterisks. For additional security, you can combine it with maxLength and autoCapitalize: 'none'.
onChangeText is called on every text change, including insertion and deletion of a single character. This is normal behavior for a controlled component. For optimization, you can use debounce or update state on onEndEditing.
TextInput does not support nested elements directly. The solution is to create a View container with Flexbox, inside which you place an icon and TextInput. The container style mimics the input field border, and TextInput stretches to fill the remaining space.
On Android, TextInput by default has a bottom border (Material Design). Disable it with underlineColorAndroid: 'transparent'. This prop works only on Android and removes the visual line under the text.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also