Next Input Focus on React Native
Tags: ref, reactnative, form, input
Published: 2019-09-19 08:46:51

---
title: Next Input Focus on React Native
published: true
description: Focus on the next input after edit on current text input on React Native
tags: ref, react native, form, input
---

You must be familiar of using Tab key to focus to next element when browsing the web. It's a simple trick to make your browsing experience easier. Recently, I am making an app with React Native that has a one-time password (OTP) form. I am planning to give the same experience when user inserts a number the app will focus to the next `TextInput`.

This can be done by using `ref` attribute. Ref allows us to access the React component or DOM node that is going to be modified. Basically, what we are going to do are

1. Create an array consist of `React.createRef`
2. Add the `ref` attribute to the inputs
3. Create a function to handle `onChange` from the inputs
4. Focus the next input found


```javascript
class OtpForm extends React.Component {
    constructor(props){
    	super(props)
      	this.inputRefs = [
        	React.createRef(),
          	React.createRef(),
          	React.createRef(),
          	React.createRef()
        ]
        // or 
        // this.inputRefs = Array(4).fill(React.createRef())
    }
}
```

Now above we already have an array of `React.createRef`. We only need 4 digits of OTP and one digit for each inputs. So we gonna add these elements to our `render` method.

```javascript
...
   render(){
     return (
       <View>
         <Text>Enter OTP</Text>
         <View style={{ flexDirection: 'row' }}>
           <TextInput maxLength="1" />
           <TextInput maxLength="1" />
           <TextInput maxLength="1" />
           <TextInput maxLength="1" />
         </View>
       </View>
     )
   }
...
```

Notice that we have not add the `ref` attr to any `TextInput`. To make it easier we will rewrite those code to render `TextInput` based on our `this.inputRefs` length, then we add the `ref` attr.

 
```javascript
...
   render(){
     return (
       <View>
         <Text>Enter OTP</Text>
         <View style={{ flexDirection: 'row' }}>
          {
            this.inputRefs.map((k, idx) => (
              <TextInput ref={r => this.inputRefs[idx] =  r} maxLength="1" />
            ))
          }
         </View>
       </View>
     )
   }
...
```

So basically, we iterate through our `this.inputRefs` using `.map` operator then we define the `ref` attr for each `TextInput` according to its index.

Now we already have our `this.inputRefs` array elements connected to each of the `TextInput`. The next thing is handling changes made by user. Since our `TextInput` only going to contain 1 digit number so we only need to handle `onChange` event. We are going to make a function `_goNextAfterEdit` that will set focus on the next input element.


```javascript
class OtpForm extends React.Component {
    constructor(props){
    	super(props)
      	this.inputRefs = [
        	React.createRef(),
          	React.createRef(),
          	React.createRef(),
          	React.createRef()
        ]
    }

    // Pass the index of the current TextInput
    // then plus that with +1 
    _goNextAfterEdit(index){
        this.inputRefs[index+1].focus()
    }

    render(){
     return (
       <View>
         <Text>Enter OTP</Text>
         <View style={{ flexDirection: 'row' }}>
          {
            this.inputRefs.map((k, idx) => (
              <TextInput onChange={() => this._goNextAfterEdit(idx)} ref={r => this.inputRefs[idx] =  r} maxLength="1" />
            ))
          }
         </View>
       </View>
     )
   }
}
```

That's it!

Basically those code satisfy our purpose. But there are additional code you can add to avoid bugs or improve functionality, such as:

#### Validate the last `TextInput`

Since we render our `TextInput` based on the length of `this.inputRefs`, there will be a bug when user is editing the last `TextInput` provided inside the form. 

```javascript
...
   _goNextAfterEdit(index){
     if(index < this.inputRefs.length) {
       this.inputRefs[index+1].focus()
     }
   }
...

```

#### Handling > 1 digit text input

You might not want to use `onChange` event when having `TextInput` that receive word or > 1 digit character. I suggest using `onSubmitEditing` which fires when the user submit button from his/her keyboard.


#### Specify the input type

In React Native, you specify the keyboard displayed whenever the user is editing the `TextInput`. You can specify it by adding the `keyboardType` attr. For the complete list of keyboard type, [https://facebook.github.io/react-native/docs/textinput.html#keyboardtype](React Native TextInput Keyboard Type)