Documentation Index
Fetch the complete documentation index at: https://mintlify.com/facebook/react-native/llms.txt
Use this file to discover all available pages before exploring further.
useWindowDimensions is a React hook that returns the current dimensions of the application window. It automatically updates when the window is resized, making it ideal for creating responsive layouts.
Signature
function useWindowDimensions(): {
width: number;
height: number;
scale: number;
fontScale: number;
}
Returns
An object containing:
width - The width of the window in density-independent pixels (dp)
height - The height of the window in density-independent pixels (dp)
scale - The pixel density of the device (e.g., 2 for @2x, 3 for @3x)
fontScale - The font scale factor set by the user’s accessibility settings
Android only:
densityDpi - The screen density expressed as dots-per-inch
Usage
import { useWindowDimensions, View, Text } from 'react-native';
function ResponsiveComponent() {
const { width, height, scale, fontScale } = useWindowDimensions();
return (
<View>
<Text>Window Width: {width}</Text>
<Text>Window Height: {height}</Text>
<Text>Pixel Density: {scale}x</Text>
<Text>Font Scale: {fontScale}</Text>
</View>
);
}
Common Patterns
Responsive Layout
import { useWindowDimensions, View, StyleSheet } from 'react-native';
function ResponsiveLayout() {
const { width } = useWindowDimensions();
// Switch between mobile and tablet layouts
const isTablet = width >= 768;
return (
<View style={isTablet ? styles.tabletContainer : styles.mobileContainer}>
{/* Your content */}
</View>
);
}
const styles = StyleSheet.create({
mobileContainer: {
flexDirection: 'column',
padding: 16,
},
tabletContainer: {
flexDirection: 'row',
padding: 24,
},
});
Dynamic Grid Columns
import { useWindowDimensions, FlatList, View } from 'react-native';
function GridView({ data }: { data: any[] }) {
const { width } = useWindowDimensions();
// Calculate number of columns based on width
const getNumColumns = () => {
if (width >= 1024) return 4;
if (width >= 768) return 3;
if (width >= 480) return 2;
return 1;
};
const numColumns = getNumColumns();
const itemWidth = width / numColumns - 16;
return (
<FlatList
data={data}
numColumns={numColumns}
key={numColumns} // Force re-render on column change
renderItem={({ item }) => (
<View style={{ width: itemWidth, margin: 8 }}>
{/* Item content */}
</View>
)}
/>
);
}
Orientation-Aware Layout
import { useWindowDimensions, View, Text } from 'react-native';
function OrientationAware() {
const { width, height } = useWindowDimensions();
const isPortrait = height > width;
const isLandscape = width > height;
return (
<View>
<Text>Orientation: {isPortrait ? 'Portrait' : 'Landscape'}</Text>
<View
style={{
flexDirection: isPortrait ? 'column' : 'row',
}}
>
{/* Layout that adapts to orientation */}
</View>
</View>
);
}
Accessibility-Aware Typography
import { useWindowDimensions, Text, StyleSheet } from 'react-native';
function AccessibleText() {
const { fontScale } = useWindowDimensions();
// Adjust layout based on user's font size preferences
const baseFontSize = 16;
const scaledFontSize = baseFontSize * fontScale;
return (
<Text style={[styles.text, { fontSize: baseFontSize }]}>
This text respects system font scaling ({fontScale.toFixed(2)}x)
</Text>
);
}
const styles = StyleSheet.create({
text: {
// fontSize will be scaled by the system automatically
// but you can use fontScale for layout adjustments
},
});
Responsive Image Sizing
import { useWindowDimensions, Image, View } from 'react-native';
function ResponsiveImage({ source }: { source: any }) {
const { width, scale } = useWindowDimensions();
// Calculate optimal image size
const imageWidth = Math.min(width * 0.9, 600);
const imageHeight = imageWidth * 0.75; // 4:3 aspect ratio
// Use scale to load appropriate resolution
const shouldLoadHighRes = scale >= 2;
return (
<View style={{ alignItems: 'center' }}>
<Image
source={source}
style={{ width: imageWidth, height: imageHeight }}
resizeMode="cover"
/>
</View>
);
}
Modal Positioning
import { useWindowDimensions, View, Modal, StyleSheet } from 'react-native';
function CenteredModal({ visible, children }: { visible: boolean; children: React.ReactNode }) {
const { width, height } = useWindowDimensions();
const modalWidth = Math.min(width * 0.9, 500);
const modalHeight = Math.min(height * 0.8, 600);
return (
<Modal visible={visible} transparent>
<View style={styles.backdrop}>
<View
style={[
styles.modalContent,
{
width: modalWidth,
height: modalHeight,
},
]}
>
{children}
</View>
</View>
</Modal>
);
}
const styles = StyleSheet.create({
backdrop: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
},
modalContent: {
backgroundColor: 'white',
borderRadius: 12,
padding: 20,
},
});
Dimensions vs useWindowDimensions
useWindowDimensions is preferred over the Dimensions API for components because:
- Automatic updates: The hook automatically re-renders your component when dimensions change
- React lifecycle: Properly integrates with React’s component lifecycle
- No manual cleanup: Subscriptions are managed automatically
// ❌ Old way - requires manual subscription management
import { Dimensions, useEffect, useState } from 'react-native';
function OldWay() {
const [dimensions, setDimensions] = useState(Dimensions.get('window'));
useEffect(() => {
const subscription = Dimensions.addEventListener('change', ({ window }) => {
setDimensions(window);
});
return () => subscription.remove();
}, []);
return <View style={{ width: dimensions.width }} />;
}
// ✅ New way - hook handles everything
function NewWay() {
const { width } = useWindowDimensions();
return <View style={{ width }} />;
}
Implementation Details
This hook:
- Uses
useState to store current dimensions
- Subscribes to dimension changes in a
useEffect
- Handles missed updates between initial render and subscription
- Filters out no-op updates when dimensions haven’t actually changed
- Automatically cleans up subscriptions on unmount
iOS
Returns width, height, scale, and fontScale.
Android
Returns width, height, scale, fontScale, and densityDpi.
Window vs Screen
This hook returns window dimensions (the visible app area), not screen dimensions. On Android with split-screen, this reflects only your app’s window.
- The hook efficiently prevents unnecessary re-renders by comparing dimension values
- Only updates state when dimensions actually change
- Subscription cleanup is automatic and efficient
See Also