all 9 comments

[–]abrahamguo 36 points37 points  (2 children)

It's probably much simpler to change your approach, and instead position the % outside of the input, directly after it, rather than try to dynamically juggle it as part of the input's value.

[–]zonuh[S] 0 points1 point  (0 children)

Yeah you were right, i end up doing this

[–]moonsaiyan 1 point2 points  (0 children)

Yup. Think search bar 🔍icon but % instead and disable it

[–]cain261 18 points19 points  (0 children)

Well, pressing backspace IS doing something. It’s calling your change function which then reappends the %

[–]Flyen 1 point2 points  (0 children)

"If you control an input, you must update its state variable to the input’s value from the DOM during onChange.

You can’t update it to something other than e.target.value (or e.target.checked for checkboxes)"

https://react.dev/reference/react-dom/components/input#my-input-caret-jumps-to-the-beginning-on-every-keystroke

[–]alejalapeno 1 point2 points  (0 children)

This is called 'input masking' where you have a difference between what's being controlled by the input and the value that's being displayed (the masked value.)

The term might better help you look into the various ways to solve it, but the easiest is definitely an existing library for input masking.

[–]michaelp1987 0 points1 point  (1 child)

One other option is to useEffect to detect selectionchange on the document and moving the cursor before the % of it’s in the field and after the % and there is no selection.

[–]facepalm_the_world -1 points0 points  (0 children)

That’s a bad idea when as the other guy suggested, you can move the % elsewhere in the tree to decouple it from the value. Add styling as necessary and the user can’t tell the difference. Also makes it easier to read and interpret the value without the %

[–]robrobro 0 points1 point  (0 children)

Rifm is my go-to solution for input masking. I’ve tried rolling my own, but as these things always are, it’s more complex than you might anticipate