skip to content

In React Native, how do autoComplete, textContentType and secureTextEntry tell the OS what a TextInput holds, for address and password autofill?

level: middleimportance: should knowfreq 40%

answer

  1. semantic hints, not validation
  2. one cross-platform prop, one iOS prop
  3. on iOS autoComplete becomes textContentType
  4. textContentType wins if both set
  5. secureTextEntry masks, never with multiline

basics

~20 s

autoComplete is the cross-platform autofill hint (street-address, postal-code, tel, new-password); on iOS React Native translates it into textContentType, the iOS-only prop, which wins if both are set. secureTextEntry masks the characters; it stores nothing and does not work with multiline.

solid answer

~40 s

Autofill works when the OS knows what each field means. `autoComplete` takes HTML-style values such as `street-address`, `address-line1`, `postal-code`, `tel`, `current-password`, `new-password` and `one-time-code`; on Android React Native maps them to Android's autofill hints, and on iOS it converts them into the equivalent `textContentType`, for example `postal-code` to `postalCode`. `textContentType` is the iOS-only prop and takes precedence when both are set, so the docs advise not setting both. To opt out, use `autoComplete="off"` on Android or `textContentType="none"` on iOS. `secureTextEntry` masks what the user types, defaults to `false` and does not work with `multiline`; it neither encrypts nor stores anything. Password fields combine it with a password hint so the OS offers saved credentials or a generated password.

code

tsx · 21 lines
tsx
import {useState} from 'react';
import {Pressable, Text, TextInput, View} from 'react-native';

export function SaveAccountFields() {
  const [hidden, setHidden] = useState(true);
  return (
    <View>
      <TextInput placeholder="Postcode" autoComplete="postal-code" />
      <TextInput placeholder="Phone" keyboardType="phone-pad" autoComplete="tel" />
      <TextInput placeholder="Email" keyboardType="email-address" autoComplete="username" autoCapitalize="none" />
      <TextInput
        placeholder="Create a password"
        secureTextEntry={hidden}
        autoComplete="new-password"
      />
      <Pressable onPress={() => setHidden(h => !h)}>
        <Text>{hidden ? 'Show password' : 'Hide password'}</Text>
      </Pressable>
    </View>
  );
}

go deeper

for a junior

Recall that autoComplete is the cross-platform autofill hint, textContentType is iOS-only, and secureTextEntry masks input.

for a middle

Explain how TextInput maps autoComplete to Android hints and to textContentType on iOS, why textContentType wins if both are set, and secureTextEntry's multiline limit.

for a senior

Configure credential and address fields so the OS offers saved data and generated passwords, and keep masking separate from how the value is stored.

for a principal

Treat autofill coverage as a conversion lever at checkout, and set conventions so every form declares field meaning consistently across platforms.

## Autofill needs meaning, not just a keyboard Both platforms can fill a form from the user's saved data: addresses, phone numbers, passwords and one-time codes. They can only do that reliably when each field declares **what it contains**. In React Native that declaration is a prop on `TextInput`, separate from `keyboardType`, which only picks a keyboard. ## autoComplete: the cross-platform hint `autoComplete` accepts HTML-style values. Those that work on both platforms include: - addresses: `street-address`, `address-line1`, `address-line2`, `postal-code`, `country`; - people: `name`, `given-name`, `family-name`, `email`, `tel`; - credentials: `username`, `current-password`, `new-password`, `one-time-code`; - `off`, to disable. Some values are **iOS-only** (for example `organization`, `url`) or **Android-only** (for example `postal-address-locality`, `sms-otp`). What happens under the hood differs by platform: | Platform | What `TextInput` does with `autoComplete` | |---|---| | Android | maps the HTML-style value to Android's autofill hint and passes it to the native field | | iOS | converts it to the matching `textContentType`, such as `postal-code` to `postalCode`, `tel` to `telephoneNumber`, `new-password` to `newPassword` | On Android the system always tries autofill using its own heuristics; `autoComplete="off"` disables it for a field, and `importantForAutofill` controls whether the field takes part at all. ## textContentType: the iOS prop `textContentType` is **iOS-only** and uses Apple's names: `fullStreetAddress`, `streetAddressLine1`, `postalCode`, `telephoneNumber`, `username`, `password`, `newPassword`, `oneTimeCode`, `none` and many more. It **takes precedence** over `autoComplete` when both are set, which is why the docs say to avoid using both: a mismatch silently wins on iOS. In a modern codebase, a single `autoComplete` value per field usually covers both platforms, with `textContentType` reserved for iOS values that have no `autoComplete` equivalent. ## secureTextEntry: masking, nothing more `secureTextEntry` makes the field **obscure** its characters, like a password field. Key facts: - default is `false`; - it **does not work with `multiline={true}`**; - it does **not** encrypt, store or protect the value in memory: once in JavaScript state it is an ordinary string, and where you keep it afterwards is a storage decision; - a "show password" toggle simply flips `secureTextEntry`. For password autofill, combine it with a meaning hint: 1. **Sign-in**: `secureTextEntry` plus `autoComplete="current-password"`, and `autoComplete="username"` on the account field, so the OS offers saved credentials. 2. **New account**: `secureTextEntry` plus `autoComplete="new-password"`, so the OS can offer to save it and, on iOS, suggest a strong generated password. 3. **iOS password rules**: `passwordRules` describes requirements for generated passwords when the field is a new password. 4. **Verification codes**: `autoComplete="one-time-code"` lets the OS suggest a code that arrived by SMS. ## When autofill does not appear 1. **Check the value.** A platform-only value, such as an iOS-only one on Android, gives that platform nothing to work with. Prefer the cross-platform list. 2. **Check for an override.** A leftover `textContentType` wins on iOS even when `autoComplete` is correct. 3. **Check Android participation.** `importantForAutofill="no"` or `'noExcludeDescendants'` on the field, or on a parent, removes it from autofill. 4. **Check the device.** Autofill depends on the user's saved data and settings; the docs note, for example, that iOS password generation needs AutoFill Passwords and iCloud Keychain switched on. ## The checkout form A grocery checkout asks for a street address, an apartment or unit, a postcode and a phone number, and offers to create an account to save them: | Field | Hint | |---|---| | Street address | `autoComplete="address-line1"` (or `street-address` for a single line) | | Apartment or unit | `autoComplete="address-line2"` | | Postcode | `autoComplete="postal-code"` | | Phone | `autoComplete="tel"` | | New password | `secureTextEntry` with `autoComplete="new-password"` | Correct hints turn four fields of typing into one tap, which matters most on a small screen at the end of a shop.

  • In React Native, what happens on iOS if a TextInput sets autoComplete="postal-code" and textContentType="telephoneNumber"?
    `textContentType` wins. `TextInput` only derives a `textContentType` from `autoComplete` when none is set, so iOS treats the field as a phone number and offers phone suggestions for a postcode. This is why the docs advise against setting both: the mismatch is silent. Android still receives the `autoComplete` hint.
  • In React Native, why can't a delivery-notes TextInput use secureTextEntry together with multiline?
    The docs state that `secureTextEntry` does not work with `multiline={true}`: masking is a single-line text field feature. A multiline field that needs to hide its content needs a different design, but free-text notes rarely need masking at all.

saying these in an interview costs you the question

  • secureTextEntry encrypts the value before it reaches JavaScript.
  • textContentType works on both iOS and Android.
  • Setting both autoComplete and textContentType is the safest way to cover both platforms.
  • keyboardType="phone-pad" is enough for the OS to autofill a phone number.
  • autoComplete values are ignored on iOS.