Get cursor position, text and key in a React Native TextInput onKeyPress

651 Views Asked by At

I need to get the current cursor position, the current text value and the pressed key of a TextInput when the text value changes, either in onKeyPress or in onChangeText.

For example, typing "A" should result in the following:

  • keyboardKey: 'A'
  • text: 'A'
  • cursorPosition: 1

Then, typing "B" should result in:

  • keyboardKey: 'B'
  • text: 'AB'
  • cursorPosition: 2

I tried to achieve that by listening to onKeyPress, onChangeText and onSelectionChange (getting start and end from nativeEvent.selection) but without any success as the events are probably happening asynchronously so using useState() or useRef() didn't help in order to get the latest values of the three in any of the eents.

<TextInput
  onChangeText={onChangeText}
  onKeyPress={onKeyPress}
  onSelectionChange={onSelectionChange}
/>

I also tried getting the text value from a reference of the TextInput in onKeyPress but this didn't work either.

Finally, tried with setting all three values as states and listening for their changes in useEffect but this wouldn't work because the function will get executed if any of the values change and I want this to be called only once per key press. In addition, I'm not getting the latest values of cursorPosition and text for some reason.

useEffect(() => {
    console.log('useEffect', keyboardKey, cursorPosition, text)
  }, [keyboardKey, cursorPosition, text]);
1

There are 1 best solutions below

0
On

I don't think there is a way you can get the cursor position value from the TextInput itself. You would have to implement it on your own. You can use the onKeyPress prop to check what key is pressed and increment a counter that should be in the state like so:

const [cursorPosition, setCursorPosition] = useState(0);
const [text, setText] = useState("");

const onKeyPress = ({ nativeEvent: { key: string } }) => {
    // Logic to check what key is pressed if needed
    // Here I put +1 for this simple example, but you can put whatever value you want here
    setCursorPosition(cursorPosition + 1);
};

const onChangeText = (newText: string) => {
    setText(newText);
}

<TextInput onKeyPress={onKeyPress} onChangeText={onChangeText} />

You can then use the setCursorPosition function to update your cursor position and then read it from cursorPosition. Same goes for text.