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 frommeasure(...)
, then wrapping it in asetTimeout
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.