0

I want to get the vertical offset of a React Native TextInput in the onFocus event for that element. I have the following code in a TextInputCustom component I created:

let textInput;

<TextInput
    onFocus={(evt) => {
        textInput.measure((x, y, width, height, pageX, pageY) => {
            console.log('textInput.measure', x, y, width, height, pageX, pageY);
        });
    }}
    ref={(ref) => textInput = ref}
/>

This "works", in that I can see a value for pageY, but the problem is that when I add multiple TextInputCustom components to a screen, it seems to report out the same pageY value for all of them, as if the ref is shared by all of them or something like that. (Honestly, I'm not sure what's going on, but I'm sure that they're all reporting out the same pageY value, even though they're all clearly at differing vertical offsets.)

I was thinking about changing textInput.measure to evt.target.measure, but evt.target seems to be an element ID and not an actual element. I read some stuff on SO about using ReactNativeComponentTree to get the actual element from the element ID, but I can't seem to properly require/import it.

At this point I'm stuck, and looking for any advice on how to properly get the vertical offset of a TextInput element when it's focused on, even when there are multiple TextInput elements on a given screen. Thank you.


Edit: Max, as per your comments, I modified my functional component as follows:

const TextInputCustom = (props) => {
    const textInputElem = useRef(null);

    <TextInput
        onFocus={(evt) => {
            textInputElem.current.measure((x, y, width, height, pageX, pageY) => {
                console.log('textInput.measure', x, y, width, height, pageX, pageY);
            });
        }}
        ref={textInputElem}
    />
};

I've noticed that the onFocus event fires for the first TextInputCustom component on the screen, but none of the others. Any thoughts? Thank you.

HartleySan
  • 7,404
  • 14
  • 66
  • 119
  • you have many textinputs so you need just as many refs. You only have 1, textInput, which is getting overwritten every render – Max May 19 '20 at 18:51
  • Yeah, that's the feeling I'm getting, but what is confusing is that the code above is in its own component, so I would think that each instance of the component would have its own local `textInput` variable that would store the ref for just that instance. All the same, is there any good way around this issue or way to use `evt.target` to get just the input that was focused on? Thank you. – HartleySan May 19 '20 at 18:54
  • if every component has its own ref then it should be fine. It's hard to tell what's wrong without entire example, e.g. this line `let textInput;` is it outside of component somewhere in the file? If yes then all instances will share one variable and owerwrite each other. Is it inside render method? then you are better off with class property. Is it inside of a functional component? then you should be using useRef – Max May 19 '20 at 19:02
  • Max, I modified my question as per your comments. Any thoughts? Thank you. – HartleySan May 19 '20 at 19:13
  • 1
    Max, please ignore my last comment. It actually works. I wasn't properly testing things. Thank you so much for your advice. Thanks. – HartleySan May 19 '20 at 19:15

0 Answers0