Tabbing Through Input Fields
On the web, it’s common to tab through forms, an intuitive and UX-friendly pattern. You get this out of the box with web forms, but when building apps with React Native, you need to implement this functionality yourself. Fortunately, it’s a cinch to set up.
First, let’s understand what native UX we’re trying to emulate on React Native.
Here’s a video of navigation through the native iOS contacts app:
And here’s a video of navigation through a Web form:
In summary, the iOS web browser gives us next and previous buttons, but for a native iOS app, these aren’t present, and React Native doesn’t support them natively, either.
I believe the reason for this discrepancy is that, natively, the “return” key performs double duty, tabbing through the form and submitting once the form is complete. On the web, the “return” key will submit the form by default, necessitating the next/previous buttons.
We’ll focus on emulating the native functionality, relying on the “return” key to tab through the form and submit it when complete.
We’ll be using
View from the
react-native library, like so:
TextInput defines its own keyboard that appears when focused. This allows a particular input field to specify
numpad, or a number of different options.
TextInputs are also responsible for determining which input to send focus to next, and they provide a handy prop for implementing this.
The first thing we’ll need is to capture the
ref of a particular input field.
If you’re not familiar, a
ref is a reference to the React component. It’s best practice to specify a callback function and capture the referenced component from the arguments.
In our example, we’re storing each
TextInput‘s ref on an internal
inputs object we’ll define in the constructor. We specify a custom index we’ll use later to focus on the input.
Since the ref is defined in the
render function, don’t store the reference with
setState; doing so will cause an infinite loop and many tears will be shed.
Next, we need to focus on the next element. We do that by hooking into the
onSubmitEditing prop and supplying it with a custom focus function on the component.
Then, we set up the field. If we zoom out to the component level:
Two things to point out:
- We need to bind the focus function to the class so we have an accurate reference to
this. This is generally done in the constructor.
- The focus action accepts a key indicating which input to focus on. That key matches what we use in the
Sometimes as we’re tabbing between fields, the keyboard will disappear and reappear. We can avoid this by using a prop on
This property forces the keyboard to remain visible. Since we’re immediately tabbing to our next field, this behavior works nicely for us.
Updating the return key to match the correct action isn’t strictly necessary (and natively iOS doesn’t change its appearance) but I think updating to the relevant return key type is a nice touch:
This indicates how to show a
done return key on the final input, and a
next return key on the rest of em.
The final gist is here:
You can see it in action on iOS and Android: