I am trying to intercept key events from a input field in React. I want to replace every key with a different one and keep the caret position where it is. Now, I have tried onChange and onKeyDown listeners.
If I use onChange like below, input field keeps its caret in its place.
<Input
type="text"
placeholder="Kelime"
onChange={(hadise) => {
hususlar.kelimeTebdiliHalinde(hadise.target.value);
}}
value={hususlar.kelime}
/>
However, if I try to do something like below, caret jumps to the end of input field.
<Input
type="text"
placeholder="Kelime"
onChange={(hadise) => {
const metin = hadise.target.value + "3";
hususlar.kelimeTebdiliHalinde(metin);
}}
value={hususlar.kelime}
/>
I have started to believe, this target.value is not a simple string or React is doing something in onChange and caret position is kept as it is when target.value is touched.
In case of onKeyDown, I am replacing the key and adding it to string, then changing the state to redraw input field. This also causes to lose caret's position.
I have tried to find target.value's type but I could not.
I can solve this issue with keeping caret's position in a ref and using it to update caret position in a useEffect but I don't want to this. I want to understand its cause and solve it in a better way.
By default, when you change the value of a text input, the cursor automatically sets itself to the end of the text. Since (most people) write from left to right, it makes sense to set the cursor to the very end after any input.
When you add the character "3" to the end of the output from
event.target.value, you are essentially accomplishing the same thing as if the user themselves had typed the character "3".This behavior can be modified using
input.setSelectionRange(). However, in your case there would be a few extra steps. Firstly, you would need a ref containing the input DOM element. Then, inside the onChange handler, you need to callinputRef.current.setSelectionRange(position, position). If you always wanted the cursor to be 1 character before the end of the output, this would be simple:If you need to put it at a specific position, then you just need to keep track of whatever position you want with a piece of state (not a ref). You could update the state in the onChange handler as needed.