React Native 의 Dimmesion API

eeensu·2026년 2월 18일

React Native

목록 보기
12/35

Dimensions API

React Native에서 화면 크기(너비, 높이)를 구할 때 사용하는 가장 기초적인 도구인 Dimensions API에 대해 알아보자.

특징

  • 현재 앱이 실행되고 있는 디바이스의 가로, 세로 픽셀 값을 반환한다.
  • 반환되는 단위는 픽셀(px)이 아니라 dp (density-independent pixel) 포인트 값이다. CSS 픽셀과 같다고 보면 된다.

사용법

import { Dimensions } from 'react-native';

// 'window'나 'screen' 중 하나를 선택해서 가져온다.
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;

console.log(`너비: ${windowWidth}, 높이: ${windowHeight}`);

window vs screen의 차이

Dimensions.get()을 쓸 때 인자로 'window'와 'screen' 중 하나를 넣어야 하는데, iOS에서도 기술적으로는 screen이 약간 더 크지만(상태바 영역 포함), 실용적으로는 거의 동일한 값이 나오기 때문에 큰 차이가 없다.

  1. window (추천)
    현재 나의 앱이 실제로 사용할 수 있는 영역의 크기다.

    • Android : 상단 상태 바(Status Bar)나 하단 소프트 키(네비게이션 바) 영역을 제외한 크기를 알려준다. (소프트 키가 있는 폰에서는 screen보다 작게 나온다.)
    • iOS : 전체 화면 크기와 동일하다.
  2. screen

  • 디바이스의 물리적인 전체 화면 해상도다.
  • 상태 바, 소프트 키 포함해서 그냥 액정 전체 크기를 말한다.
  • 결론 : 앱 UI를 짤 때의 대부분의 상황은 window를 써야 한다. 우리가 그릴 곳은 소프트 키 위쪽이기 때문이다.

단점과 함정

Dimensions.get('window')는 아주 편리해 보이지만, 치명적인 단점이 하나 있다.
바로 이 값은 한 번 가져오면 변하지 않는 상수로 박제된다는 것이다.

다음과 같은 문제 상황을 보자.

  1. 앱을 켰다. (세로 모드, 너비 360) -> width 변수에 360이 들어감.
  2. 폰을 가로로 돌렸다. (가로 모드)
  3. 하지만 width 변수는 여전히 360이다. 화면은 넓어졌는데 변수는 업데이트가 안 된 것이다.
  4. 해결책 : 화면이 돌아갈 때마다 값을 새로 가져오도록 이벤트 리스너를 달아줘야 한다.
import React, { useState, useEffect } from 'react';
import { View, Text, Dimensions } from 'react-native';

const DimensionsExample  = () => {
  // 초기값 설정
  const [windowDimensions, setWindowDimensions] = useState(Dimensions.get('window'));

  useEffect(() => {
    // 1. 화면 크기가 변할 때(회전, 폴더블폰 펼침) 실행될 함수
    const onChange = ({ window }) => {
      setWindowDimensions(window);
    };

    // 2. 리스너 등록
    const subscription = Dimensions.addEventListener('change', onChange);

    // 3. 청소 (Cleanup)
    return () => subscription.remove();
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>너비: {windowDimensions.width}</Text>
      <Text>높이: {windowDimensions.height}</Text>
    </View>
  );
};

useWindowDimensions

React Native 팀도 Dimensions API 쓰는 게 귀찮다는 걸 알고, Hook을 만들어줬다.

  • Dimensions API를 매핑한 훅이다.
  • 화면 크기가 바뀌면(회전 등) 알아서 리렌더링을 시켜준다. (리스너 등록할 필요 없음)
  • 코드가 훨씬 깔끔하다.
import React from 'react';
import { View, Text, useWindowDimensions } from 'react-native';

const BestPracticeExample = () => {
  // 그냥 이거 한 줄이면 끝이다. 회전하면 알아서 값이 바뀜.
  const { width, height } = useWindowDimensions();

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>너비: {width}</Text>
      <Text>높이: {height}</Text>
      {/* 화면이 넓으면 가로 배치, 좁으면 세로 배치 같은 반응형 UI 가능 */}
      <View style={{ flexDirection: width > 500 ? 'row' : 'column' }}>
         {/* ... */}
      </View>
    </View>
  );
};



추가로 알면 좋은 것들

1. PixelRatio API

Dimensions와 함께 자주 쓰이는 API인데, 아래와 같이 dp와 실제 물리 픽셀 간의 변환이 필요할 때 사용한다.

  • 고해상도 이미지 선택 (1x, 2x, 3x 이미지 중 어떤 걸 로드할지)
  • 정확한 1px 라인 그리기 (StyleSheet.hairlineWidth 대신)
import { PixelRatio } from 'react-native';

// 디바이스의 픽셀 밀도 (1x, 2x, 3x 등)
const pixelDensity = PixelRatio.get();

// dp를 실제 픽셀로 변환 (이미지 최적화할 때 필수)
const dpToPixel = PixelRatio.getPixelSizeForLayoutSize(100); // 100dp -> ?px

// 물리 픽셀을 dp로 변환
const pixelToDp = PixelRatio.roundToNearestPixel(2.7); // 2.66666 -> 3

2. 반응형 디자인 패턴

import { Dimensions } from 'react-native';

const { width: SCREEN_WIDTH } = Dimensions.get('window');

// 디자인 기준 너비 (피그마 디자인이 375px 기준이라고 가정)
const BASE_WIDTH = 375;

// 비율로 크기 계산
export const scale = (size: number) => (SCREEN_WIDTH / BASE_WIDTH) * size;

// 폰트는 너무 크게/작게 되지 않도록 제한
export const moderateScale = (size: number, factor = 0.5) => 
  size + (scale(size) - size) * factor;

// 사용 예시
<Text style={{ fontSize: moderateScale(16) }}>
  모든 폰에서 적절한 크기로 보임
</Text>

3. Tablet/Foldable 대응

import { useWindowDimensions } from 'react-native';

const ResponsiveLayout = () => {
  const { width } = useWindowDimensions();
  
  // 화면 크기에 따른 레이아웃 분기
  const isTablet = width >= 768;
  const columns = isTablet ? 3 : 1;
  
  return (
    <View style={{ 
      flexDirection: isTablet ? 'row' : 'column',
      gap: 16 
    }}>
      {/* 태블릿에서는 3단 그리드, 폰에서는 1단 리스트 */}
    </View>
  );
};

4. Dimension을 쓰면 안되는 경우

  • 부모 컴포넌트의 크기를 알고 싶을 때 → onLayout 이벤트 사용
  • 키보드가 올라왔을 때 남은 공간 계산 → KeyboardAvoidingView 또는 react-native-keyboard-controller 사용
  • 복잡한 반응형 UI → react-native-size-matters 라이브러리 추천
profile
안녕하세요! 프론트엔드 개발자입니다! (2024/03 ~)

0개의 댓글