Most of form validation is choosing the right keyboard, and Apple tells you when to check.
Adding form validation to a mobile app comes down to two decisions, and only the second one is really code. The first is which keyboard each field opens, because a field that accepts digits alone should never have handed anybody a letter to type. React Native sets that with keyboardType, which documents seven values that work on both platforms, five that work on iOS alone and one that works on Android alone. The second decision is the moment you check what was typed, and Apple answers it by field type rather than with a single rule. An email address is best checked once the person moves to the next field. A user name or a password has to be checked before they move. If you have not built the screen yet, the earlier step is make an app.
What follows is the list of props React Native actually documents for this job, what the toolbar above the iOS keyboard can and cannot hold, which callback fires at which moment, and what Apple says about putting the error on screen. That last one runs against the habit most forms have, so it is the section to read if you only read one.
Start hereThe short version
Stop the bad input first. Then check once, at the right moment.
Prevention is cheaper than correction and the platform does most of it for free. A numeric keyboard removes whole categories of error before the person can make one. maxLength caps the length at the input rather than after it, and React Native recommends that over writing the same limit in JavaScript, because the version in JavaScript shows the extra character and then takes it away again. autoComplete tells the system what the field is for, which means the fastest way to fill it correctly is a single tap on a suggestion the person never has to proofread.
What is left after that is the small set of rules the platform cannot know, such as whether the password matches your policy or whether the quantity is actually in stock. Those need a check, a moment to run it, and somewhere on screen to say what went wrong. Apple is specific about the moment and specific about the somewhere, and neither answer is the one most forms use.
What does React Native give you to validate with?
No validation library, and that is the first thing to be clear about. React Native documents a component, TextInput, with props that shape what can be typed and callbacks that tell you when something happened. The rules themselves are yours. What the component does give you is a long list of ways to make a wrong value harder to produce.
keyboardType is the headline. Its enum holds thirteen values. Seven of them are listed as working across platforms: default, number-pad, decimal-pad, numeric, email-address, phone-pad and url. Five are marked iOS only: ascii-capable, numbers-and-punctuation, name-phone-pad, twitter and web-search. One is marked Android only, visible-password. There is a second, newer prop called inputMode, which React Native describes as working like the inputmode attribute in HTML and as having precedence over keyboardType. That precedence is the detail to remember, because if a component library sets inputMode somewhere in its own code your keyboardType will look broken and the reason will be two files away.
Autofill is the other half, and it is split across two props for historical reasons. autoComplete works on both platforms and takes a long list of hints, from email and username through cc-number to one-time-code. textContentType is iOS only and covers similar ground, with username or password enabling autofill of login details from the device keychain and oneTimeCode marking a field that can be filled by a code arriving in an SMS. React Native says in a note on the page that autoComplete provides the same functionality for all platforms, that you should avoid setting both, and that textContentType takes precedence when both are set. There are a few smaller traps in the same reference. secureTextEntry does not work with multiline. autoCapitalize is not supported by some keyboard types, name-phone-pad among them. A listed known issue, react-native#26799, says Android does not support secureTextEntry when keyboardType is email-address or phone-pad.
React Native, TextInput, footer dated 14 October 2026, read 23 October 2026
Check yours
What each field type should be set to
Tick the fields your form has. The prop values on the left are the ones in React Native's own TextInput reference, read on 23 October 2026. The note on the right is the documented catch for that field, or the timing Apple gives for it.
Nothing ticked. A form of plain text boxes with no keyboard hints is the version that produces the most bad data, because the person was handed a full alphabet for a field that only ever wanted digits.
Should you check the field before or after it loses focus?
There is a documented answer, and it is not one rule. Apple's Human Interface Guidelines page on text fields asks you to validate fields when it makes sense, and then says the appropriate time to check the data depends on the context. It gives two worked cases. For an email address, it is best to validate when the person switches to another field. For a user name or a password, the validation needs to happen before they switch. So the guidance really is split on which side of losing focus you sit, and the field type decides.
The reasoning holds up once you try it. A half-typed email address is not wrong, it is unfinished, so a check that runs on the fourth character calls a correct address invalid and makes the person argue with the form. A password rule is different. Eight characters and a digit can be tested at every keystroke, and the person wants to know at keystroke seven rather than after they have moved on. The same goes for a user name that has to be unique, except there the check is a network call and you have to decide what the field looks like while it is in flight.
A second Apple page pushes in the earlier direction more generally. The guidelines page on entering data asks you to validate field values dynamically, noting that people get frustrated when they have to go back and fix mistakes after filling in a long form, and that verifying values as people enter them gives them the chance to correct an error right away. The same page says that where data entry is required, people should understand they have to supply it before they can continue, and offers the example of keeping a Next or Continue button unavailable until the required fields are filled. Put the two pages together and the default is to check as you go, with email addresses as the named exception. The text fields page also suggests a number formatter for numeric data, which configures the field to accept only numeric values, and warns against assuming how the value will be presented because formatting varies by locale.
Apple, Human Interface Guidelines, Text fields, change log dated 5 June 2023, read 23 October 2026
What is the bar above the keyboard, and where does it break?
React Native calls it the input accessory view, and it has its own component. InputAccessoryView is described on its reference page as enabling customisation of the keyboard input accessory view on iOS, displayed above the keyboard whenever a TextInput has focus, and usable for building custom toolbars. This is where a Done button lives when the number pad has no return key, and where a Next button lives if you want to walk somebody down a long form without them reaching for the screen.
The wiring is two props that have to agree. You wrap your toolbar in InputAccessoryView and set its nativeID to a string, then pass that same string as the inputAccessoryViewID of the TextInput you want it attached to. The component itself takes only backgroundColor, nativeID and style, so whatever is inside it is your own layout. A related iOS prop, inputAccessoryViewButtonLabel, overrides the default button label, and React Native notes the default label is not localised, which makes that prop necessary rather than cosmetic for any app shipping in more than one language.
Two limits are printed on the component's own page as known issues, and both bite late. react-native#18997 says it does not support a multiline TextInput, so a notes field cannot have the toolbar that every other field has. react-native#20157 says it cannot be used with a bottom tab bar, which is a problem that arrives when someone adds tabs to an app whose forms already worked. The other thing to plan for is that none of this exists on Android, because the component is documented as iOS only. Android keyboards have their own action key, configured through returnKeyType and returnKeyLabel, so the two platforms need different plans for the same gesture.
Which callback fires, and when
The middle column paraphrases React Native's own description of each one. The right column is whether it is a sound place to hang a check. Two of these have documented exceptions that are easy to miss in testing, and both of those exceptions are on iOS.
| Prop | What the reference says | Safe place for a check |
|---|---|---|
| onChangeText | Fires on every change. The changed text arrives as a single string argument. | Yes, and this is the one Apple's guidance points at |
| onBlur | Fires when the input is blurred. React Native warns the text on the event object can be undefined. | As a trigger only, never as the source of the value |
| onEndEditing | Fires when text input ends. React Native names it as where to read the last value. | Yes |
| onSubmitEditing | Fires when the submit button on the keyboard is pressed. Not called on iOS with a phone-pad keyboard. | Only with a second check that does not depend on it |
| onKeyPress | Fires before onChange. On Android it handles soft keyboard input only, not a hardware keyboard. | No |
| maxLength | Not an event. Caps the characters that can be entered at all, which React Native recommends over doing it in JavaScript. | Better than validating, because nothing bad gets typed |
One more prop decides whether two of those fire together. submitBehavior controls what the return key does. On a single line input the default is blurAndSubmit, which blurs the field and sends a submit event, so a blur check and a submit check both run on one press. The explicit value submit sends the event without blurring. On a multiline input the default is newline, so the return key adds a line and your submit handler never runs at all. A field that drives a list rather than a submit button is a different shape of problem, and that one is in add filters and sorting.
How should the app show the error once it finds one?
Next to the field, in words, and not in a pop-up. Apple's guidelines do not have a page called validation, so the answer sits across two others. The page on feedback asks you to consider putting status feedback into the interface near the items it describes, so that people get the information without having to take action or leave their current context. The page on alerts asks you to use alerts sparingly, and says to avoid using one merely to provide information, because people do not appreciate an interruption that is informative but not actionable. A failed field is the exact case those two sentences describe between them.
There is a wording trap worth naming, because it is probably why so many apps get this wrong. The text fields page says your app needs to alert people if they have entered characters other than digits. Read quickly, that sounds like permission to show a modal alert. Read against the alerts page, which is explicit about reserving that component for information people have to act on now, it clearly means tell them. The message belongs under the field it is about, where the person can still see what they typed.
Colour is not enough on its own. The feedback page asks you to make all feedback accessible and to use more than one channel for it, naming colour, text, sound and haptics, so the message still lands whether somebody has silenced their device, looked away from the screen or is using VoiceOver. A red border passes none of those tests. A red border with a sentence beside it passes all of them, because the sentence is also the only part a screen reader can say out loud. The same page asks you to show people when a command cannot be carried out and to help them understand why, which rules out the message that says only that something is invalid. If a half-filled form has to survive the app being closed, that is a storage question rather than a validation one, and it is answered in add bookmarks.
Newly is an AI app builder that writes this kind of screen for you. You describe the form in plain English and it produces a real React Native and Expo project you own, with two-way GitHub sync, so the keyboard types and the error text are code you can read and change rather than settings in somebody else's tool. It uploads iOS builds to TestFlight, publishes to Google Play internal testing and builds a standalone Android APK. It is $25 a month, with no free tier. What it will not do is press submit on the App Store for you, because Apple guideline 4.2.6 requires apps made with an app generation service to be submitted by the owner of the content. The steps for that are in publish to app store.
Questions people ask about validating a form in an app
One prop, keyboardType, with thirteen values in its enum. Seven of them work on both platforms: default, number-pad, decimal-pad, numeric, email-address, phone-pad and url. Five work on iOS only: ascii-capable, numbers-and-punctuation, name-phone-pad, twitter and web-search. One works on Android only, visible-password. There is also inputMode, which React Native describes as working like the inputmode attribute in HTML, with the values none, text, decimal, numeric, tel, search, email and url. Read from the TextInput reference on 23 October 2026, a page whose footer gives its own last update as 14 October 2026.
Write down the fields. The keyboard follows from them.
List every field on your form and what kind of thing goes in it. That list already decides the keyboard, the autofill hint and which side of losing focus the check belongs on, which is most of the work done before anybody writes a rule.
Start building