The Dimensions API provides access to device screen dimensions. Use it to get the width and height of the window and screen, and listen for dimension changes (like device rotation).
Import
import { Dimensions } from 'react-native';
For React components, prefer using the useWindowDimensions hook instead of Dimensions.get() for automatic updates on dimension changes.
Methods
get()
Returns the dimensions for a given dimension type.
const dimensions = Dimensions.get(dim);
The dimension type to retrieve:
'window': The visible window dimensions (excludes status bar, navigation bar on Android)
'screen': The entire screen dimensions (includes status bar, navigation bars)
Returns: DisplayMetrics object with:
width (number): Width in pixels
height (number): Height in pixels
scale (number): Pixel density (e.g., 2 for @2x, 3 for @3x)
fontScale (number): Font scaling factor for accessibility
addEventListener()
Add a listener for dimension changes.
const subscription = Dimensions.addEventListener(type, handler);
Must be 'change' - fires when dimensions change (e.g., device rotation).
Callback invoked with an object containing window and screen dimensions.
Returns: EventSubscription - Object with a remove() method to unsubscribe.
Types
DisplayMetrics
type DisplayMetrics = {
width: number;
height: number;
scale: number;
fontScale: number;
};
DimensionsPayload
type DimensionsPayload = {
window: DisplayMetrics;
screen: DisplayMetrics;
};
Examples
Basic Usage
import { Dimensions } from 'react-native';
const windowDimensions = Dimensions.get('window');
const screenDimensions = Dimensions.get('screen');
console.log('Window:', windowDimensions);
// { width: 375, height: 667, scale: 2, fontScale: 1 }
console.log('Screen:', screenDimensions);
// { width: 375, height: 812, scale: 2, fontScale: 1 }
Responsive Styles
import React from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
const ResponsiveComponent = () => {
return (
<View style={styles.container}>
<Text>Window Width: {width}</Text>
<Text>Window Height: {height}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
width: width * 0.9, // 90% of screen width
height: height * 0.5, // 50% of screen height
padding: 20,
},
});
Listening to Dimension Changes
import React, { useEffect, useState } from 'react';
import { Dimensions, View, Text } from 'react-native';
const DimensionTracker = () => {
const [dimensions, setDimensions] = useState({
window: Dimensions.get('window'),
screen: Dimensions.get('screen'),
});
useEffect(() => {
const subscription = Dimensions.addEventListener(
'change',
({ window, screen }) => {
setDimensions({ window, screen });
},
);
return () => subscription?.remove();
}, []);
return (
<View>
<Text>Window Width: {dimensions.window.width}</Text>
<Text>Window Height: {dimensions.window.height}</Text>
<Text>Screen Width: {dimensions.screen.width}</Text>
<Text>Screen Height: {dimensions.screen.height}</Text>
</View>
);
};
Using useWindowDimensions Hook
import React from 'react';
import { useWindowDimensions, View, Text } from 'react-native';
const WindowDimensionsExample = () => {
const { width, height, scale, fontScale } = useWindowDimensions();
return (
<View>
<Text>Width: {width}</Text>
<Text>Height: {height}</Text>
<Text>Scale: {scale}</Text>
<Text>Font Scale: {fontScale}</Text>
</View>
);
};
Orientation Detection
import React, { useEffect, useState } from 'react';
import { Dimensions, View, Text } from 'react-native';
const OrientationDetector = () => {
const [orientation, setOrientation] = useState('portrait');
const determineOrientation = () => {
const { width, height } = Dimensions.get('window');
setOrientation(width > height ? 'landscape' : 'portrait');
};
useEffect(() => {
determineOrientation();
const subscription = Dimensions.addEventListener('change', () => {
determineOrientation();
});
return () => subscription?.remove();
}, []);
return (
<View>
<Text>Current Orientation: {orientation}</Text>
</View>
);
};
Responsive Grid Layout
import React from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';
const { width } = Dimensions.get('window');
const ITEM_MARGIN = 10;
const ITEMS_PER_ROW = width > 768 ? 4 : 2; // 4 columns on tablet, 2 on phone
const ITEM_SIZE = (width - (ITEMS_PER_ROW + 1) * ITEM_MARGIN) / ITEMS_PER_ROW;
const GridItem = () => (
<View style={styles.item} />
);
const GridLayout = () => (
<View style={styles.container}>
{Array.from({ length: 8 }).map((_, i) => (
<GridItem key={i} />
))}
</View>
);
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
flexWrap: 'wrap',
padding: ITEM_MARGIN,
},
item: {
width: ITEM_SIZE,
height: ITEM_SIZE,
margin: ITEM_MARGIN,
backgroundColor: '#3498db',
},
});
import { Dimensions, Platform } from 'react-native';
const { width, height } = Dimensions.get('window');
// Check if device is a tablet
const isTablet = () => {
const aspectRatio = height / width;
return Math.min(width, height) >= 600 && aspectRatio < 1.6;
};
// Get safe area adjustments
const getSafeAreaPadding = () => {
if (Platform.OS === 'ios') {
// iPhone X and newer have different safe areas
return height >= 812 ? 44 : 20;
}
return 0;
};
Dynamic Font Sizing
import React from 'react';
import { Text, StyleSheet, Dimensions } from 'react-native';
const { width } = Dimensions.get('window');
// Scale font size based on screen width
const scaleFont = (size) => {
const baseWidth = 375; // iPhone 8 width as base
return (width / baseWidth) * size;
};
const ResponsiveText = () => (
<Text style={styles.text}>This text scales with screen size</Text>
);
const styles = StyleSheet.create({
text: {
fontSize: scaleFont(16),
},
});
Window vs Screen
window
- Represents the visible application area
- iOS: Excludes status bar
- Android: Excludes status bar and bottom navigation bar (if using edge-to-edge mode)
- Recommended for most layout calculations
screen
- Represents the entire physical screen
- Includes all system UI elements
- Remains constant even when keyboard is visible
- Useful for fullscreen calculations
const windowDims = Dimensions.get('window');
const screenDims = Dimensions.get('screen');
console.log('Window height:', windowDims.height); // 667
console.log('Screen height:', screenDims.height); // 812
console.log('Status bar height:', screenDims.height - windowDims.height); // 145
Understanding Scale
The scale property indicates the pixel density:
const { width, scale } = Dimensions.get('window');
const physicalPixels = width * scale;
console.log('Logical points:', width); // 375
console.log('Scale factor:', scale); // 2
console.log('Physical pixels:', physicalPixels); // 750
Common scale values:
1: Standard resolution (mdpi on Android)
2: Retina/@2x (iPhone 8, xhdpi on Android)
3: Super Retina/@3x (iPhone 14, xxhdpi on Android)
Best Practices
Use useWindowDimensions() hook in React components instead of Dimensions.get() for automatic updates on dimension changes.
Don’t cache dimension values in StyleSheet.create() - dimensions won’t update on rotation. Calculate styles dynamically or use state.
The fontScale property reflects the user’s font size accessibility setting. Multiply your font sizes by this value to respect user preferences.
Common Pitfalls
Static Styles Don’t Update
// ❌ Bad: Dimensions cached in StyleSheet
const styles = StyleSheet.create({
container: {
width: Dimensions.get('window').width, // Won't update on rotation!
},
});
// ✅ Good: Use hook or state
const { width } = useWindowDimensions();
return <View style={{ width }} />;
Missing Cleanup
// ❌ Bad: Listener not cleaned up
useEffect(() => {
Dimensions.addEventListener('change', handler);
}, []);
// ✅ Good: Remove listener on cleanup
useEffect(() => {
const subscription = Dimensions.addEventListener('change', handler);
return () => subscription?.remove();
}, []);