React Native 접근성 폼 완전 가이드

발행: (2026년 6월 7일 AM 12:25 GMT+9)
8 분 소요
원문: Dev.to

출처: Dev.to

모바일 앱 어디에서든 폼이 존재합니다 – 인증 흐름, 데이터 입력, 지원 요청, 온보딩 등… 앱에 로그인 화면이 있다면, 폼은 새 사용자가 가장 먼저 마주하는 요소일 가능성이 높습니다. 따라서 접근성은 선택이 아니라 첫인상이 됩니다.

문제는 폼이 보조 기술 사용자에게 가장 많이 망가지는 영역 중 하나라는 점입니다. 라벨 누락, 키보드 함정, 조용히 사라지는 검증 오류, 제출 후 포커스가 사라지는 현상 등은 사용자 중 상당수가 앱을 사용할 수 없게 만듭니다.

이 가이드는 React Native에서 모든 사용자를 위해 작동하는 폼을 만드는 완전한 레퍼런스입니다. 사용자가 손가락, 외부 키보드, 스크린 리더, 음성 입력 등 어떤 방법으로 탐색하든 적용됩니다. 코드 예제는 무엇을 해야 하는지왜 그렇게 해야 하는지를 모두 보여줍니다.

실제 기기에서 포크하고 테스트할 수 있는 완전한 데모 레포가 제공됩니다 – rn-accessible-form-demo에서 확인하세요.


Labels

모든 폼 필드에는 텍스트 입력, 체크박스, 라디오/제출 버튼 여부와 관계없이 라벨이 필요합니다. 예외는 없습니다.

플레이스홀더에 의존하지 마세요

플레이스홀더 텍스트는 사용자가 입력을 시작하자마자 사라집니다. 스크린 리더는 처음에 이를 읽지만, 사라진 뒤에는 사용자가 입력을 지우지 않는 한 해당 필드가 무엇을 위한 것인지 알 방법이 없습니다. 플레이스홀더는 힌트용으로만 사용하고 라벨로는 사용하지 마세요.

시각 라벨 + accessibilityLabel 사용

스크린 리더가 같은 정보를 두 번 읽는 것을 방지하려면(시각 라벨과 입력 라벨 각각), 시각 라벨을 보조 기술에서 숨기고 전체 라벨을 입력 자체에 넣습니다.

<Label
  style={styles.label}
  importantForAccessibility="no"
  accessibilityElementsHidden={true}
>
  Email address*
</Label>

importantForAccessibility="no"는 Android를, accessibilityElementsHidden은 iOS를 처리합니다. 두 속성을 함께 사용하면 보조 기술에게 시각 라벨을 완전히 건너뛰도록 지시하고, TextInput에 설정된 accessibilityLabel이 스크린 리더에 대한 유일한 진실 원천이 됩니다.

Required fields

필수 필드는 시각적인 별표가 아니라 accessibilityLabel 안에 선언합니다. 별표가 무엇을 의미하는지 스크린 리더 사용자는 알 수 없기 때문입니다.

// ❌ Screen reader reads "Email address" — no indication it's required

// ✅ Screen reader reads "Email address, required"

When to use accessibilityHint

라벨에 포함되지 않는 추가 컨텍스트(예: 형식 안내, 필드 용도, 상호작용 후 동작 등)는 accessibilityHint를 사용합니다. 라벨과 역할 뒤에 읽히며, 사용자는 접근성 설정에서 힌트를 끌 수 있으므로 중요한 정보를 여기 두면 안 됩니다.

// 예시 코드 생략

Headings

폼 제목이나 섹션 헤딩에는 accessibilityRole="header"를 사용합니다. 스크린 리더 사용자는 헤딩을 기준으로 빠르게 섹션을 이동할 수 있으며, 일반 텍스트가 아니라 헤딩으로 읽혀집니다.

<Text accessibilityRole="header" style={styles.heading}>
  Contact Us
</Text>

Radio Buttons and Predefined Options

선택 가능한 옵션이 미리 정의된 경우, 라디오 버튼이 자유 텍스트 입력보다 접근성이 높습니다. 사용자는 모든 선택지를 한눈에 보고 타이핑 없이 선택할 수 있어 오류와 인지 부하를 줄일 수 있습니다—특히 스크린 리더나 키보드로 탐색하는 사용자에게 유리합니다.

각 옵션에는 accessibilityRole="radio"를, 컨테이너에는 accessibilityRole="radiogroup"을 지정합니다. 그룹 역할은 옵션들이 서로 연관돼 있음을 스크린 리더에 알립니다. accessibilityState={{ selected }}를 사용해 선택 상태를 반영하면 스크린 리더가 라벨과 함께 “selected” 또는 “not selected”를 읽어줍니다.

<TouchableOpacity
  accessibilityRole="radio"
  accessibilityState={{ selected: selectedOption === 'email' }}
  onPress={() => setSelected('email')}
>
  {/* custom styled radio UI */}
</TouchableOpacity>

<TouchableOpacity
  accessibilityRole="radio"
  accessibilityState={{ selected: selectedOption === 'phone' }}
  onPress={() => setSelected('phone')}
>
  {/* custom styled radio UI */}
</TouchableOpacity>

오류 처리는 텍스트 입력과 동일한 패턴을 따릅니다 – 오류 메시지를 그룹의 accessibilityLabel에 포함하고 포커스를 그룹 컨테이너로 이동합니다. 자세한 내용은 아래를 참고하세요.


법적·재정적 영향을 미치는 모든 동작(예: 약관 동의, 구독 신청, 결제 확인)에서는 옵션을 명시적인 체크박스로 제공해야 합니다. 사용자는 동의를 가정당하지 않고, 의도적이고 충분히 정보를 얻은 선택을 해야 합니다.

accessibilityRole="checkbox"accessibilityState={{ checked }}를 사용합니다.

<TouchableOpacity
  accessibilityRole="checkbox"
  accessibilityState={{ checked }}
  onPress={() => setChecked(v => !v)}
>
  {/* custom styled checkbox UI */}
</TouchableOpacity>

체크박스가 필수이며 제출 시 체크되지 않았다면, 오류는 다른 필드와 동일하게 포커스를 체크박스로 이동하고 accessibilityLabel에 오류를 포함하는 방식으로 처리합니다.


Keyboard Behaviour

사용자는 화면 키보드의 Return 키만으로 폼 전체를 탐색할 수 있어야 하며, 중간에 멈추지 않아야 합니다.

Set the correct keyboard type

입력 유형에 맞는 키보드를 지정하면 인지 부하를 줄이고 오류를 방지할 수 있습니다.

// 예시 코드 생략

일반적인 값: default, email-address, numeric, phone-pad, decimal-pad. 전체 목록은 React Native 문서에서 확인하세요.

returnKeyType

마지막 필드를 제외한 모든 필드에 returnKeyType="next"를, 마지막 필드에는 returnKeyType="done"을 설정합니다. 이렇게 하면 사용자는 현재 위치와 Return 키를 눌렀을 때의 동작을 알 수 있습니다.

0 조회
Back to Blog

관련 글

더 보기 »

모바일 한여름 열풍

!Cover image for Mobile Midsommer Madnesshttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploa...