React Native: Getting the position of an element React Native: Getting the position of an element ios ios

React Native: Getting the position of an element


React Native provides a .measure(...) method which takes a callback and calls it with the offsets and width/height of a component:

myComponent.measure( (fx, fy, width, height, px, py) => {    console.log('Component width is: ' + width)    console.log('Component height is: ' + height)    console.log('X offset to frame: ' + fx)    console.log('Y offset to frame: ' + fy)    console.log('X offset to page: ' + px)    console.log('Y offset to page: ' + py)})

Example...

The following calculates the layout of a custom component after it is rendered:

class MyComponent extends React.Component {    render() {        return <View ref={view => { this.myComponent = view; }} />    }    componentDidMount() {        // Print component dimensions to console        this.myComponent.measure( (fx, fy, width, height, px, py) => {            console.log('Component width is: ' + width)            console.log('Component height is: ' + height)            console.log('X offset to frame: ' + fx)            console.log('Y offset to frame: ' + fy)            console.log('X offset to page: ' + px)            console.log('Y offset to page: ' + py)        })            }}

Bug notes

  • Note that sometimes the component does not finish rendering before componentDidMount() is called. If you are getting zeros as a result from measure(...), then wrapping it in a setTimeout should solve the problem, i.e.:

    setTimeout( myComponent.measure(...), 0 )


You can use onLayout to get the width, height, and relative-to-parent position of a component at the earliest moment that they're available:

<View  onLayout={event => {    const layout = event.nativeEvent.layout;    console.log('height:', layout.height);    console.log('width:', layout.width);    console.log('x:', layout.x);    console.log('y:', layout.y);  }}>

Compared to using .measure() as shown in the accepted answer, this has the advantage that you'll never have to fiddle around deferring your .measure() calls with setTimeout to make sure that the measurements are available, but the disadvantage that it doesn't give you offsets relative to the entire page, only ones relative to the element's parent.


I had a similar problem and solved it by combining the answers above

class FeedPost extends React.Component {  constructor(props) {    ...    this.handleLayoutChange = this.handleLayoutChange.bind(this);  }handleLayoutChange() {    this.feedPost.measure( (fx, fy, width, height, px, py) => {      console.log('Component width is: ' + width)      console.log('Component height is: ' + height)      console.log('X offset to page: ' + px)      console.log('Y offset to page: ' + py)    })  }  render {    return(      <View onLayout={(event) => {this.handleLayoutChange(event) }}       ref={view => { this.feedPost = view; }} >...

Now I can see the position of my feedPost element in the logs:

08-24 11:15:36.838  3727 27838 I ReactNativeJS: Component width is: 15608-24 11:15:36.838  3727 27838 I ReactNativeJS: Component height is: 20608-24 11:15:36.838  3727 27838 I ReactNativeJS: X offset to page: 18808-24 11:15:36.838  3727 27838 I ReactNativeJS: Y offset to page: 870