React Native OTP Input

Learn via video courses
Topics Covered

Overview

The react-native-otp-input is a compact JavaScript library that offers a sophisticated user interface for entering one-time passcodes (OTPs). It effectively manages input suggestions on iOS whenever an OTP SMS is received. On Android, the library conveniently autofills the OTP when the user taps the copy button in the SMS notification bar. Additionally, it includes a thoughtfully designed flow to handle unexpected user gestures. Although a default user interface is provided, you have the flexibility to customize its appearance according to your preferences.

Installations and Dependencies

Use the below command to install react-native-otp-input in your project. For npm users:

For yarn users:

React Native Otp Input uses @react-native-community/clipboard to handle the clipboard in this package, So you should install @react-native-community/clipboard.

Install @react-native-community/clipboard in your project using the below command.

For npm users:

For yarn users:

Parameters

ParameterRequiredDescription
pinCountYESSpecifies the number of digits in the component
codeNOAllows the usage of this library as a controlled/uncontrolled component by providing this prop or not
codeInputFieldStyleNODetermines the style of the input field when it is not focused
codeInputHighlightStyleNOSpecifies the style of the input field when it is focused
autoFocusOnLoadNOAutomatically activates the input and displays the keyboard when the component is loaded
onCodeChangedNOCallback function triggered when the digits in the input field are changed
onCodeFilledNOCallback function triggered when the last digit is entered
secureTextEntryNOHides the contents of text fields
editableNODefines whether the inputs are editable or not
keyboardAppearanceNOSets the appearance of the keyboard ('default', 'dark', 'light')
keyboardTypeNOSpecifies the type of keyboard to be displayed
clearInputsNOOption to clear the inputs after entering the code
placeholderCharacterNOThe character or string used as a placeholder in the individual code input fields
placeholderTextColorNOSets the color of the placeholder character

For Basic Usage:

For More Advanced Usage:

Use Cases

The react-native-otp-input library is commonly used in React Native applications for handling one-time password (OTP) input functionality. Some of the use cases for react-native-otp-input include:

  • User verification:
    React Native applications often require user verification through OTPs sent via SMS or email. The library provides a convenient way to capture and validate OTPs entered by users.

  • Two-factor authentication (2FA):
    Many applications use OTPs as an additional layer of security for user authentication. React-native-otp-input helps in capturing and verifying OTPs during the 2FA process.

  • Account recovery:
    In case of account recovery or password reset scenarios, OTPs are often used to verify the user's identity. The library assists in capturing and validating the OTP entered by the user for account recovery purposes.

  • Transaction verification:
    Some applications require OTPs to validate transactions or sensitive actions. React-native-otp-input facilitates capturing and verifying OTPs to ensure the security and integrity of transactions.

How to Create Split OTP Input Fields?

The idea behind incorporating the split OTP feature revolves around utilizing the TextInput component as our main point of reference or, in simpler terms, as our primary source. A customized View resembling a box will be rendered for each digit entered into this text input. Subsequently, the text input will be concealed and accessed when necessary using the useRef Hook.

To enhance the visibility of our implementation, I made the background color of the container View darker.

In the provided code snippet, our entry file, App.js, is presented, demonstrating an adjustment made to the background color.

TextInput Component Rendering

Next, our focus shifts towards establishing the components directory. Within this directory, there will be an additional folder named OTP, designed to accommodate the OTPInput.js and Styles.js files.

The OTPInput.js file will encompass two components that are implemented using the styled component library: TextInputHidden, serving as the concealed text input, and OTPInputContainer, which contains the actual text input.

Presented below is the content of our Styles.js file:

And here is the code in our OTPInput.js file:

Next, we will incorporate the OTPInput component into the App.js file, enabling us to display the complete execution within our emulator or simulator.

In App.js, we will begin by setting up certain states and then transmit them as props to the OTPInput.js file.

One of the initial states will be code, which initially holds an empty string and will be responsible for storing the input value entered into the respective input field.

The next stage is referred to as isPinReady, which is initially set to false and will only be set to true when the user has entered the expected number of digits. To accommodate your specific use case, we will define the maximum length of the expected numbers as four.

Subsequently, these states will be passed as a prop to the OTPInput component. In App.js, we will then destructure all the values passed as props and transfer them to the OTPInput.js component, where they will be utilized in TextInputHidden.

Following that, we will assign the value of the TextInput component to the code state and associate the onChangeText event with the setCode function. As the user inputs values, the onChangeText event will update the code state, which was initially set as an empty string.

Considering that only numerical input is anticipated for the input field, we will set the keyboardType to number-pad and limit the maxLength to the specified maximum number of four.

To handle the onBlur event, which occurs when the input loses focus, we will employ the useRef Hook and a handleOnBlur function. By using useRef, we can create a reference variable initialized as null and the handleOnBlur function will be declared for future usage.

Finally, in our App.js file, we will establish all the necessary states and subsequently pass them as props to the OTPInput component, as exemplified below:

Upon examining OTPInput.js, we will encounter the properties that were assigned to the OTPInput component and extract them for utilization.

Creating Components for Split Input Boxes

In the next step, our focus will be on developing distinct elements for the separate input boxes. Initially, our attention will be on building a customized Pressable component named SplitOTPBoxesContainer, which will incorporate specific style attributes. Subsequently, we will proceed to generate a View component known as SplitBoxes to effectively present the divided boxes, along with a text component called SplitBoxText responsible for exhibiting the relevant text content.

The code within our Styles.js file can be observed below:

About OTPInput.js, our focus will be on positioning the SplitOTPBoxesContainer element above the TextInputHidden component.

Within the SplitOTPBoxesContainer, we will iterate through the digits of the TextInputHidden component and display a corresponding box for each of them. By utilizing the Array.fill() method, we will generate an array with a maximum length of four and assign an initial value of 0 to each input field index.

Upon printing the boxArray to the console, the outcome obtained is as follows:

Next, we will proceed with creating a function that will handle the mapping of values in the array and display a box for each value. This function will be utilized to receive both the value and index from the Array.map method.

Initially, we define an emptyInput variable, which is an empty string intended to be displayed when an input box does not have any value. By utilizing the index, we extract each digit from the input string provided. If a digit is empty, the function will return the emptyInput variable that we declared previously.

Following this, the View component responsible for SplitBoxes will be returned along with the SplitBoxText. The value for SplitBoxText will be the extracted digit, and the index will be assigned as the key for the SplitBoxes.

Within the SplitOTPBoxesContainer, we will iterate over the boxArray and apply the boxDigit function to render the split boxes. Consequently, this will result in the rendering of boxes based on the number of digits present in the boxArray, which is four in this case.

We will proceed with the implementation of these functionalities in our OTPInput.js file.

Afterward, we have the option to examine the divided containers within our emulator/simulator and input various data.

Highlighting the Current OTP Digit

To achieve the desired functionality, we aim to implement a feature where the current input box is visually highlighted by changing its background color and activating the keyboard when pressed. It is important to note that we have a component called SplitOTPBoxesContainer, which is capable of being pressed. To enable this behavior, we will assign the handleOnPress function to the onPress prop of SplitOTPBoxesContainer.

To facilitate this, we will introduce a Boolean state that serves the purpose of determining whether we are currently focused on an input box. By default, this state will be initialized as false for all input boxes. Within the handleOnPress function, we will update the focus state to true and utilize the inputRef to ensure the input box is in focus. Conversely, the handleOnBlur function will be responsible for resetting the focus state to false.

Once implemented, users will be able to press on the TextInput, enter their desired PIN digits, and observe them being displayed in both the split boxes and the TextInput component.

To finalize the current box highlight, a new styled component named SplitBoxesFocused will be generated within the Styles.js file. This component will be derived from SplitBoxes, with alterations made to the background and border-color properties.

Within the boxDigit function, several variables will be initialized. Firstly, we will have isCurrentValue, which serves to verify whether the current digit or box being examined corresponds to the current value in the mapping. Next, isLastValue is utilized to determine if the digit being processed is the final one.

To ascertain whether the code has been completed, we employ isCodeComplete, which evaluates if the code's length matches the previously specified maximum length.

Lastly, isValueFocused is employed to establish whether the value is under focus. This condition holds true if it is either the current or last value, and if the code has been fully entered.

To alternate between the SplitBoxes and SplitBoxesFocused, our aim is to establish a distinction by introducing a fresh variable named StyledSplitBoxes. When both the text input and value receive attention, we intend to display SplitBoxesFocused; otherwise, we will present SplitBoxes. Consequently, by substituting StyledSplitBoxes with SplitBoxes, we can ensure that our focused input box appears with the designated background color.

Loading Split Input Fields with Dynamism

If we desire to enhance the visual appeal of our app with a touch of liveliness, what steps can we take? One approach involves employing the useEffect Hook, enabling us to modify the state of setIsPinReady to true once all the necessary digits have been successfully entered.

A new code dependency was introduced to ensure that useEffect executes only when there is a change in the code value. Subsequently, we will modify the TextInputHidden styled component to maintain complete control over it while concealing it completely.

Hiding the Keyboard if Pressed Outside the Split Box

To dismiss the keyboard, users can simply tap anywhere on the screen outside the designated input areas when the keyboard is visible. To achieve this functionality, React Native provides the Pressable and Keyboard components.

To implement it, we need to replace the View component that currently wraps the text input with the Pressable component. Additionally, we should attach the onPress function to invoke the keyboard.dismiss function, as demonstrated in the example below:

Final Sync of the Submit Button to the OTP Input State

Suppose we have a requirement to incorporate a submit button into the design of this feature. To accomplish this, we can begin by generating the button using the TouchableOpaity and Text components, and then display it by utilizing Styles.js.

Next, within our App.js file, we will make use of the two components that were recently developed.

By utilizing the isPinReady condition, we can switch the status of this button to active or inactive based on the completion of all the entered digits.

FAQs

Q: How do I use React Native OTP Input in my application?

A: To use React Native OTP Input, you need to import the OTPInput component from the library and render it in your application's JSX code. You can customize the component by passing various props such as the number of digits, input styles, and callback functions for handling OTP completion or change events.

Q: Are there any additional features available in React Native OTP Input?

A: Apart from the basic OTP input functionality, React Native OTP Input provides additional features such as auto-focusing on the next input digit, auto-verification of OTP upon completion, and a customizable timer for automatic OTP expiration. These features can be enabled by passing the appropriate props to the OTPInput component.

Q: Does React Native OTP Input support international phone numbers and country codes?

A: Yes, React Native OTP Input has built-in support for international phone numbers and country codes. It provides props like defaultValue and defaultValueCountry, which allow you to set an initial value for the OTP input field along with the corresponding country code.

Conclusion

In conclusion,

  • React Native OTP Input is a powerful library for capturing and validating OTPs in React Native apps.
  • It simplifies OTP input and provides customization options for error messages, styles, and validation logic.
  • Features include split input fields, current digit highlighting, dynamic loading, and compatibility with international phone numbers.
  • The library enhances the user experience by providing intuitive and visually appealing OTP input functionality.
  • It can be used for capturing and validating other short numerical inputs like PIN codes or verification codes.
  • React Native OTP Input empowers developers to create robust and secure OTP input functionality.
  • By incorporating this library, developers can enhance the security, usability, and overall user experience of their apps.