Skip to main content
Version: Next

Text

텍스트를 표시하는 React 컴포넌트.

Text 컴포넌트는 중첩, 스타일링, 터치 처리 기능을 지원한다.

다음 예제에서 중첩된 제목과 본문 텍스트는 styles.baseTextfontFamily를 상속받지만, 제목은 추가적인 스타일을 직접 정의한다. 리터럴 줄바꿈으로 인해 제목과 본문이 서로 위로 쌓인다:

중첩 텍스트

안드로이드와 iOS 모두 특정 범위의 문자열에 굵은 글씨나 색상 등 서식을 지정할 수 있다(iOS에서는 NSAttributedString, 안드로이드에서는 SpannableString). 하지만 실제로 이 방법은 매우 번거롭다. 리액트 네이티브에서는 웹의 방식을 차용해 텍스트를 중첩하여 동일한 효과를 얻을 수 있도록 설계했다.

리액트 네이티브는 이 코드를 내부적으로 평평한 NSAttributedString이나 SpannableString으로 변환한다. 변환된 결과는 다음과 같은 정보를 포함한다:

"I am bold and red"
0-9: bold
9-17: bold, red

컨테이너

<Text> 엘리먼트는 레이아웃 측면에서 독특한 특징을 가진다. <Text> 안에 있는 모든 요소는 더 이상 플렉스 박스 레이아웃을 사용하지 않고 텍스트 레이아웃을 사용한다. 이는 <Text> 안에 있는 요소들이 더 이상 사각형이 아니며, 줄의 끝에 도달하면 자동으로 줄바꿈된다는 것을 의미한다.

tsx
<Text>
<Text>첫 번째 부분 그리고 </Text>
<Text>두 번째 부분</Text>
</Text>
// 텍스트 컨테이너: 공간이 허용한다면 텍스트는 인라인으로 표시된다
// |첫 번째 부분 그리고 두 번째 부분|

// 그렇지 않으면 텍스트는 하나로 이어져 흐른다
// |첫 번째 부분 |
// |그리고 두 번째 |
// |부분 |

<View>
<Text>첫 번째 부분 그리고 </Text>
<Text>두 번째 부분</Text>
</View>
// 뷰 컨테이너: 각 텍스트는 독립적인 블록으로 처리된다
// |첫 번째 부분 그리고|
// |두 번째 부분 |

// 그렇지 않으면 텍스트는 각자의 블록 안에서 흐른다
// |첫 번째 부분 |
// |그리고 |
// |두 번째 부분|

제한된 스타일 상속

웹에서 문서 전체에 폰트 패밀리와 크기를 설정하는 일반적인 방법은 상속 가능한 CSS 속성을 활용하는 것이다.

css
html {
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
font-size: 11px;
color: #141823;
}

이 폰트는 특정 엘리먼트나 그 부모 엘리먼트가 새로운 규칙을 지정하지 않는 한, 모든 엘리먼트에 상속된다.

React Native에서는 이에 대해 더 엄격하다: 모든 텍스트 노드를 <Text> 컴포넌트로 감싸야 한다. <View> 아래에 직접 텍스트 노드를 둘 수 없다.

tsx
// 잘못된 예: 예외가 발생한다. <View>의 자식으로 텍스트 노드를 둘 수 없다.
<View>
Some text
</View>

// 올바른 예
<View>
<Text>
Some text
</Text>
</View>

또한 전체 하위 트리에 기본 폰트를 설정하는 기능도 없다. 한편, fontFamily는 단일 폰트 이름만 허용하며, 이는 CSS의 font-family와 다르다. 애플리케이션 전체에서 일관된 폰트와 크기를 사용하려면 MyAppText와 같은 컴포넌트를 만들어 스타일을 포함시키고, 이를 애플리케이션 전체에서 사용하는 것이 권장된다. 이 컴포넌트를 활용해 MyAppHeaderText와 같은 더 구체적인 컴포넌트를 만들 수도 있다.

tsx
<View>
<MyAppText>
애플리케이션 전체에 적용된 기본 폰트로 스타일링된 텍스트
</MyAppText>
<MyAppHeaderText>헤더로 스타일링된 텍스트</MyAppHeaderText>
</View>

MyAppText가 스타일링을 포함한 Text 컴포넌트로 자식 엘리먼트를 렌더링하는 컴포넌트라면, MyAppHeaderText는 다음과 같이 정의할 수 있다.

tsx
const MyAppHeaderText = ({children}) => {
return (
<MyAppText>
<Text style={{fontSize: 20}}>{children}</Text>
</MyAppText>
);
};

이렇게 MyAppText를 합성하면 상위 컴포넌트의 스타일을 얻으면서도 특정 사용 사례에서 스타일을 추가하거나 재정의할 수 있다.

React Native는 여전히 스타일 상속 개념을 가지고 있지만, 텍스트 하위 트리로 제한된다. 이 경우 두 번째 부분은 볼드체이면서 빨간색이 된다.

tsx
<Text style={{fontWeight: 'bold'}}>
I am bold
<Text style={{color: 'red'}}>and red</Text>
</Text>

이렇게 텍스트 스타일링을 제한하는 방식이 더 나은 앱을 만들 것이라고 믿는다:

  • (개발자) React 컴포넌트는 강력한 격리를 염두에 두고 설계되었다. 컴포넌트를 애플리케이션 어디에든 배치할 수 있어야 하며, props가 동일하다면 동일하게 보이고 동작할 것이라고 믿을 수 있어야 한다. props 외부에서 상속될 수 있는 텍스트 속성은 이 격리를 깨뜨릴 수 있다.

  • (구현자) React Native의 구현도 단순화된다. 모든 엘리먼트에 fontFamily 필드를 둘 필요가 없으며, 텍스트 노드를 표시할 때마다 트리를 루트까지 탐색할 필요도 없다. 스타일 상속은 네이티브 Text 컴포넌트 내부에서만 인코딩되며, 다른 컴포넌트나 시스템 자체로 누출되지 않는다.

참고 문서

Props

accessibilityHint

접근성 힌트는 사용자가 접근성 엘리먼트에 대해 어떤 동작을 수행했을 때 어떤 결과가 발생할지 이해하도록 돕는다. 이는 접근성 레이블만으로는 명확하지 않은 경우에 유용하다.

타입
string

accessibilityLanguage
iOS

사용자가 엘리먼트와 상호작용할 때 스크린 리더가 사용해야 할 언어를 나타내는 값이다. 이 값은 BCP 47 사양을 따라야 한다.

자세한 내용은 iOS accessibilityLanguage 문서를 참고한다.

타입
string

accessibilityLabel

사용자가 엘리먼트와 상호작용할 때 스크린 리더가 읽는 텍스트를 재정의한다. 기본적으로 라벨은 모든 자식 엘리먼트를 탐색하고 공백으로 구분된 Text 노드를 누적하여 구성한다.

타입
string

accessibilityRole

스크린 리더가 현재 포커스된 엘리먼트를 특정 역할로 인식하도록 지시한다.

iOS에서는 이 역할들이 해당하는 Accessibility Traits에 매핑된다. 이미지 버튼은 'image'와 'button' 두 가지 트레이트가 모두 설정된 것과 동일한 기능을 한다. 자세한 내용은 Accessibility 가이드를 참고한다.

Android에서는 이 역할들이 TalkBack에서 iOS의 Voiceover와 유사한 기능을 수행한다.

타입
AccessibilityRole

accessibilityState

스크린 리더가 현재 포커스된 엘리먼트를 특정 상태로 처리하도록 지시한다.

하나의 상태를 제공하거나, 아무 상태도 제공하지 않거나, 여러 상태를 제공할 수 있다. 상태는 반드시 객체 형태로 전달해야 한다. 예를 들어 {selected: true, disabled: true}와 같이 사용한다.

타입
AccessibilityState

accessibilityActions

접근성 동작(accessibility actions)은 보조 기술이 컴포넌트의 동작을 프로그램적으로 실행할 수 있도록 한다. accessibilityActions 속성은 동작 객체의 목록을 포함해야 한다. 각 동작 객체는 namelabel 필드를 포함해야 한다.

자세한 내용은 접근성 가이드를 참고한다.

타입필수 여부
배열아니오

onAccessibilityAction

사용자가 접근성 동작을 수행할 때 호출된다. 이 함수는 수행할 동작의 이름을 포함하는 이벤트를 유일한 인자로 받는다.

자세한 내용은 접근성 가이드를 참고한다.

타입필수 여부
function아니요

accessibletrue로 설정하면 해당 뷰가 접근성 엘리먼트임을 나타낸다.

자세한 내용은 접근성 가이드를 참고한다.

타입기본값
booleantrue

adjustsFontSizeToFit

주어진 스타일 제약 조건에 맞게 글꼴 크기를 자동으로 축소할지 여부를 지정한다.

타입기본값
booleanfalse

allowFontScaling

글꼴이 접근성 설정의 텍스트 크기에 맞게 조정되어야 하는지 여부를 지정한다.

타입기본값
booleantrue

android_hyphenationFrequency
Android

Android API Level 23 이상에서 단어 줄바꿈을 결정할 때 자동 하이픈 넣기 빈도를 설정한다.

타입기본값
enum('none', 'normal','full')'none'

aria-busy

해당 엘리먼트가 수정 중임을 나타내며, 보조 기술이 변경이 완료될 때까지 기다린 후 사용자에게 업데이트를 알릴 수 있음을 의미한다.

타입기본값
booleanfalse

aria-checked

체크 가능한 엘리먼트의 상태를 나타낸다. 이 필드는 불리언 값 또는 "mixed" 문자열을 사용해 혼합된 상태의 체크박스를 표현할 수 있다.

타입기본값
boolean, 'mixed'false

aria-disabled

해당 엘리먼트가 인지 가능하지만 비활성화되어 있음을 나타낸다. 따라서 편집하거나 조작할 수 없다.

타입기본값
booleanfalse

aria-expanded

확장 가능한 엘리먼트가 현재 확장되었는지 축소되었는지를 나타낸다.

타입기본값
booleanfalse

aria-label

상호작용 가능한 엘리먼트에 대한 레이블을 정의한다.

타입
문자열

aria-selected

선택 가능한 엘리먼트가 현재 선택되었는지 여부를 나타낸다.

타입
boolean

dataDetectorType
Android

텍스트 엘리먼트에서 클릭 가능한 URL로 변환될 데이터 타입을 결정한다. 기본적으로는 어떤 데이터 타입도 감지하지 않는다.

단 하나의 타입만 지정할 수 있다.

타입기본값
enum('phoneNumber', 'link', 'email', 'none', 'all')'none'

disabled
Android

테스트 목적으로 텍스트 뷰의 비활성화 상태를 지정한다.

타입기본값
boolfalse

dynamicTypeRamp
iOS

iOS의 Dynamic Type을 이 엘리먼트에 적용할 때 사용하는 램프 설정이다.

타입기본값
enum('caption2', 'caption1', 'footnote', 'subheadline', 'callout', 'body', 'headline', 'title3', 'title2', 'title1', 'largeTitle')'body'

ellipsizeMode

numberOfLines를 설정할 때, 이 속성은 텍스트가 어떻게 잘릴지 정의한다. 이 속성은 반드시 numberOfLines와 함께 사용해야 한다.

이 속성은 다음 값 중 하나를 가질 수 있다:

  • head: 줄의 끝이 컨테이너에 맞도록 표시되고, 줄의 시작 부분에서 누락된 텍스트는 생략 부호(...)로 표시된다. 예: "...wxyz"
  • middle: 줄의 시작과 끝이 컨테이너에 맞도록 표시되고, 중간 부분에서 누락된 텍스트는 생략 부호로 표시된다. 예: "ab...yz"
  • tail: 줄의 시작이 컨테이너에 맞도록 표시되고, 줄의 끝 부분에서 누락된 텍스트는 생략 부호로 표시된다. 예: "abcd..."
  • clip: 텍스트 컨테이너의 경계를 넘어가는 줄은 그려지지 않는다.

Android에서는 numberOfLines1보다 큰 값으로 설정된 경우, tail 값만 정상적으로 동작한다.

타입기본값
enum('head', 'middle', 'tail', 'clip')tail

id

이 속성은 네이티브 코드에서 해당 뷰를 찾을 때 사용한다. nativeID 속성보다 우선순위가 높다.

타입
string

maxFontSizeMultiplier

allowFontScaling이 활성화된 상태에서 글꼴이 도달할 수 있는 최대 크기 비율을 지정한다. 가능한 값은 다음과 같다:

  • null/undefined: 부모 노드나 전역 기본값을 상속받음 (0)
  • 0: 최대값 없음, 부모/전역 기본값 무시
  • >= 1: 이 노드의 maxFontSizeMultiplier를 해당 값으로 설정
타입기본값
numberundefined

minimumFontScale
iOS

adjustsFontSizeToFit이 활성화되었을 때 폰트가 도달할 수 있는 최소 크기 비율을 지정한다. (값 범위: 0.01-1.0).

타입
number

nativeID는 네이티브 코드에서 이 뷰를 찾기 위해 사용한다.

타입
string

numberOfLines

텍스트 레이아웃을 계산한 후 줄 바꿈을 포함해 총 줄 수가 이 값을 초과하지 않도록 말줄임표로 텍스트를 잘라낸다. 이 값을 0으로 설정하면 줄 수 제한이 적용되지 않는다.

이 속성은 주로 ellipsizeMode와 함께 사용된다.

타입기본값
number0

onLayout

마운트 시와 레이아웃 변경 시 호출된다.

타입
({nativeEvent: LayoutEvent}) => void

onLongPress

이 함수는 길게 누를 때 호출된다.

타입
({nativeEvent: PressEvent}) => void

onMoveShouldSetResponder

이 뷰가 터치 응답성을 "요청"하려는지 여부를 결정한다. 뷰가 현재 응답자가 아닐 때, 뷰에서 터치 이동이 발생할 때마다 이 함수가 호출된다.

타입
({nativeEvent: PressEvent}) => boolean

onPress

사용자가 눌렀을 때 호출되는 함수로, onPressOut 이후에 트리거된다.

타입
({nativeEvent: PressEvent}) => void

onPressIn

터치가 시작되는 즉시 호출되며, onPressOutonPress보다 먼저 실행된다.

타입
({nativeEvent: PressEvent}) => void

onPressOut

터치가 해제될 때 호출된다.

타입
({nativeEvent: PressEvent}) => void

onResponderGrant

뷰가 이제 터치 이벤트에 반응하고 있다. 이 시점에서 사용자에게 어떤 일이 일어나고 있는지 강조하고 보여줄 수 있다.

안드로이드에서는 이 콜백에서 true를 반환하여, 현재 응답자가 종료될 때까지 다른 네이티브 컴포넌트가 응답자가 되지 못하도록 막을 수 있다.

타입
({nativeEvent: PressEvent}) => void | boolean

onResponderMove

사용자가 손가락을 움직이고 있다.

타입
({nativeEvent: PressEvent}) => void

onResponderRelease

터치가 끝날 때 발생한다.

타입
({nativeEvent: PressEvent}) => void

onResponderTerminate

View에서 응답자(responder)가 제거되었다. 이는 onResponderTerminationRequest 호출 후 다른 뷰가 응답자를 가져갔을 수도 있고, 운영체제가 묻지 않고 가져갔을 수도 있다(예: iOS의 제어 센터나 알림 센터에서 발생하는 경우).

타입
({nativeEvent: PressEvent}) => void

onResponderTerminationRequest

다른 View가 응답자(responder)가 되려고 하며, 현재 View에게 응답자 권한을 해제할 것을 요청한다. true를 반환하면 응답자 권한을 해제한다.

타입
({nativeEvent: PressEvent}) => boolean

onStartShouldSetResponderCapture

부모 View가 자식 View가 터치 시작 시 응답자가 되는 것을 막으려면, 이 핸들러가 true를 반환하도록 설정해야 한다.

타입
({nativeEvent: PressEvent}) => boolean

onTextLayout

텍스트 레이아웃이 변경될 때 호출된다.

타입
(TextLayoutEvent) => mixed

pressRetentionOffset

스크롤 뷰가 비활성화된 상태에서, 버튼이 비활성화되기 전에 터치가 버튼에서 벗어날 수 있는 최대 거리를 정의한다. 버튼이 비활성화된 후, 다시 버튼으로 터치를 이동시키면 버튼이 다시 활성화되는 것을 확인할 수 있다. 스크롤 뷰가 비활성화된 상태에서 이 동작을 여러 번 반복해 보자. 메모리 할당을 줄이기 위해 상수 값을 전달해야 한다.

타입
Rect, number

role

role은 보조 기술을 사용하는 사용자에게 컴포넌트의 목적을 전달한다. accessibilityRole 속성보다 우선순위가 높다.

타입
Role

selectable

사용자가 텍스트를 선택하고 기본 복사 및 붙여넣기 기능을 사용할 수 있도록 허용한다.

타입기본값
booleanfalse

selectionColor
Android

텍스트의 강조 색상을 설정한다.

타입
color

style

타입
텍스트 스타일, 뷰 스타일 프로퍼티

suppressHighlighting
iOS

true로 설정하면 텍스트를 눌렀을 때 시각적 변화가 발생하지 않는다. 기본적으로는 텍스트를 누를 때 회색 타원형으로 강조 표시된다.

타입기본값
booleanfalse

testID

이 속성은 end-to-end 테스트에서 해당 뷰를 식별하는 데 사용된다.

타입
string

textBreakStrategy
Android

Android API Level 23 이상에서 텍스트 줄바꿈 전략을 설정한다. 가능한 값은 simple, highQuality, balanced이다.

타입기본값
enum('simple', 'highQuality', 'balanced')highQuality

lineBreakStrategyIOS
iOS

iOS 14 이상에서 줄바꿈 전략을 설정한다. 가능한 값은 none, standard, hangul-word, push-out이다.

타입기본값
enum('none', 'standard', 'hangul-word', 'push-out')'none'

타입 정의

TextLayout

TextLayout 객체는 TextLayoutEvent 콜백의 일부이며, Text 라인의 측정 데이터를 포함한다.

예제

js
{
capHeight: 10.496,
ascender: 14.624,
descender: 4,
width: 28.224,
height: 18.624,
xHeight: 6.048,
x: 0,
y: 0
}

속성

이름타입선택 가능설명
ascendernumber아니오텍스트 레이아웃 변경 후 라인의 상승 높이.
capHeightnumber아니오기준선 위 대문자의 높이.
descendernumber아니오텍스트 레이아웃 변경 후 라인의 하강 높이.
heightnumber아니오텍스트 레이아웃 변경 후 라인의 높이.
widthnumber아니오텍스트 레이아웃 변경 후 라인의 너비.
xnumber아니오Text 컴포넌트 내부의 라인 X 좌표.
xHeightnumber아니오기준선과 라인의 중간선 사이의 거리 (글자 크기).
ynumber아니오Text 컴포넌트 내부의 라인 Y 좌표.

TextLayoutEvent 객체는 컴포넌트 레이아웃이 변경될 때 콜백으로 반환된다. 이 객체는 lines라는 키를 포함하며, 이 키의 값은 렌더링된 각 텍스트 줄에 해당하는 TextLayout 객체로 이루어진 배열이다.

예제

js
{
lines: [
TextLayout,
TextLayout,
// ...
];
target: 1127;
}

속성

이름타입선택 사항설명
linesTextLayout 배열아니오렌더링된 각 줄에 대한 TextLayout 데이터를 제공한다.
target숫자아니오해당 엘리먼트의 노드 ID를 나타낸다.