How to Focus Previous React Native TextInput on Backspace?
Published On: 2024-02-20
Posted By: Harish

We have seen a way to focus on the next text input after entering a value to the current input. We considered a simple OTP validation as an example. This post is a continuation of that post. Check the first post HERE.
In this post, we will see a way to focus on previous text input on deletion of value from current input. We will track the Backspace key event to focus on previous input.
Add onKeyPress Callback
We can get a backspace event with the help of onKeyPress callback. So, add onKeyPress callback to second, third and fourth text inputs and get the type of the key event.
For checking event type, we will create a new function called handleKeyPress and pass to every text input's onKeyPress callback.
...
const handleKeyPress = (e: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
    const key = e.nativeEvent.key;
    return key === "Backspace" ? true : false;
};
...
<TextInput
  ...
  onKeyPress={(e) => {
    const isBack = handleKeyPress(e);
  }}
  ...
/>
...
Function handleKeyPress returns true if the occurred event is Backspace. If not, returns false.
As we want to focus on previous text input on the backspace event, we check for truthy and use the focus() method to shift focus on to the previous field.
...
//This is the second input which will focus on the first input after deleting the second input's value.
<TextInput
  ...
  onKeyPress={(e) => {
    const isBack = handleKeyPress(e);
    if(isBack) {
      firstRef.current.focus();
    }
  }}
  ...
/>
...
Last text input will shift to the previous input event even without clicking backspace. This weird behavior is because of occurring a backspace event with an actual event when the input is empty in onKeyPress callback.
As we are checking for a backspace event to focus on the previous field, this behavior will cause it to go back to the third field without pressing any backspace.
To clear this issue, I added a condition to focus on the current field if the event is not a backspace event. In our case, that is the fourth <TextInput> field.
...
//This is the last input (fourth input) which will focus on the same input if the event is not a backspace event.
<TextInput
  ...
  onKeyPress={(e) => {
    const isBack = handleKeyPress(e);
    if(isBack) {
      thirdref.current.focus();
    } else {
      fourthRef.current.focus();
      fourthRef.current.blur();
    }
  }}
  ...
/>
...
blur() method of text input is the opposite of focus(). It removes the focus and collapses the opened keyboard.
If you run the app, it will function like the video below.
Complete code,
//app.tsx
import { useRef } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TextInput,
  NativeSyntheticEvent,
  TextInputKeyPressEventData
} from "react-native";
export const App = () => {
  const firstRef = useRef<any>(null);
  const secondRef = useRef<any>(null);
  const thirdRef = useRef<any>(null);
  const fourthRef = useRef<any>(null);
  const onKeyPress = (e: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
    const key = e.nativeEvent.key;
    return key === "Backspace" ? true : false;
  };
  return (
    <View style={styles.container}>
      <Text style={styles.text}>
        ifelsething.com
      </Text>
      <Text style={styles.text}>
        Automatically focus on previous text input on backspace.
      </Text>
      <View style={styles.block}>
        <TextInput
          maxLength={1}
          style={styles.input}
          ref={firstRef}
          textAlign='center'
          autoFocus={true}
          showSoftInputOnFocus={true}
          keyboardType='numeric'
          onChangeText={(t: string) => {
            if(!t) return;
            console.log("First: ", t)
            secondRef.current.focus();
          }}
        />
        <TextInput
          maxLength={1}
          ref={secondRef}
          style={styles.input}
          textAlign='center'
          keyboardType='numeric'
          onKeyPress={(e) => {
            const isBack = onKeyPress(e);
            if(isBack) {
              firstRef.current.focus();
            }
          }}
          onChangeText={(t: string) => {
            if(!t) return;
            console.log("Second: ", t)
            thirdRef.current.focus();
          }}
        />
        <TextInput
          maxLength={1}
          ref={thirdRef}
          style={styles.input}
          textAlign='center'
          keyboardType='numeric'
          onKeyPress={(e) => {
            const isBack = onKeyPress(e);
            if(isBack) {
              secondRef.current.focus();
            }
          }}
          onChangeText={(t: string) => {
            if(!t) return;
            console.log("Third: ", t)
            fourthRef.current.focus();
          }}
        />
        <TextInput
          maxLength={1}
          ref={fourthRef}
          style={styles.input}
          textAlign='center'
          keyboardType='numeric'
          onKeyPress={(e) => {
            const isBack = onKeyPress(e);
            if(isBack) {
              thirdRef.current.focus();
            } else {
              fourthRef.current.focus();
              fourthRef.current.blur();
            }
          }}
          onChangeText={(t: string) => {
            if(!t) return;
            console.log("Fourth: ", t)
          }}
        />
      </View>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    margin: 10,
    gap: 20
  },
  input: {
    width: 50,
    height: 50,
    borderColor: 'blue',
    borderWidth: 1,
    borderRadius: 50,
    padding: 10,
    fontSize: 20,
    color: 'black',
  },
  text: {
    fontSize: 15,
    color: 'black',
    fontStyle: 'italic'
  },
  block: {
    flexGrow: 1,
    flexDirection: 'row',
    gap: 10,
    justifyContent: 'center'
  }
});
 Change Cursor Position of React Native Text Input
Change Cursor Position of React Native Text Input Default Value and Value of React Native TextInput
Default Value and Value of React Native TextInput What is Keyboard.scheduleLayoutAnimation() Method?
What is Keyboard.scheduleLayoutAnimation() Method? Hide Cursor of React Native Text Input
Hide Cursor of React Native Text Input Get React Native TextInput Width and Height on Render
Get React Native TextInput Width and Height on Render Press Events of React Native TextInput
Press Events of React Native TextInput Enable or Disable React Native TextInput
Enable or Disable React Native TextInput