RN expose accessibility props từ iOS VoiceOver và Android TalkBack để screen reader mô tả UI cho user khiếm thị.
Props chính:
- accessible={true}: bật accessibility cho component (mặc định false cho View, true cho Text/Button).
- accessibilityLabel: text screen reader đọc. Override children text khi cần ngắn gọn hoặc rõ nghĩa hơn.
- accessibilityRole: vai trò UI (button, link, header, image, checkbox, radio, switch, ...). Screen reader đọc role + state (vd "checkbox, checked").
- accessibilityHint: hint thêm về hành động (vd "Submits the form").
- accessibilityState: { selected, disabled, checked, busy, expanded }.
- accessibilityValue: cho slider/progress bar ({ min, max, now, text }).
Ví dụ:
<Pressable
onPress={handleLike}
accessible
accessibilityRole="button"
accessibilityLabel={liked ? 'Unlike post' : 'Like post'}
accessibilityState={{ selected: liked }}
accessibilityHint="Toggles like status for this post"
>
<Icon name={liked ? 'heart-filled' : 'heart-outline'} />
</Pressable>Test screen reader:
- iOS: Settings → Accessibility → VoiceOver → bật. Triple-tap home button để toggle.
- Android: Settings → Accessibility → TalkBack → bật.
- Swipe để navigate, double-tap để activate, two-finger swipe để scroll.
Lưu ý:
- Decorative icons không nên có accessibilityLabel → set accessible={false} hoặc accessibilityElementsHidden={true}.
- Group label: dùng accessibilityLabel ở parent View với importantForAccessibility="yes-exclude-descendants" (Android) hoặc accessibilityElementsHidden cho children (iOS).
- Dynamic text (count, time) — ensure label cập nhật theo state.
- Contrast: dùng useColorScheme + design system token.
Tools:
- eslint-plugin-react-native-a11y cho lint warnings.
- iOS Accessibility Inspector (Xcode) audit visual.
RN exposes accessibility props from iOS VoiceOver and Android TalkBack so screen readers can describe the UI to vision-impaired users.
Main props:
- accessible={true}: enables accessibility for the component (defaults to false for View, true for Text/Button).
- accessibilityLabel: the text the screen reader says. Override children text when you need something shorter or clearer.
- accessibilityRole: the UI role (button, link, header, image, checkbox, radio, switch, ...). Screen readers announce role + state (e.g. "checkbox, checked").
- accessibilityHint: extra hint about the action (e.g. "Submits the form").
- accessibilityState: { selected, disabled, checked, busy, expanded }.
- accessibilityValue: for sliders/progress bars ({ min, max, now, text }).
Example:
<Pressable
onPress={handleLike}
accessible
accessibilityRole="button"
accessibilityLabel={liked ? 'Unlike post' : 'Like post'}
accessibilityState={{ selected: liked }}
accessibilityHint="Toggles like status for this post"
>
<Icon name={liked ? 'heart-filled' : 'heart-outline'} />
</Pressable>Testing screen readers:
- iOS: Settings → Accessibility → VoiceOver → enable. Triple-tap the home button to toggle.
- Android: Settings → Accessibility → TalkBack → enable.
- Swipe to navigate, double-tap to activate, two-finger swipe to scroll.
Pitfalls:
- Decorative icons should not carry an accessibilityLabel — set accessible={false} or accessibilityElementsHidden={true}.
- Group labels: put accessibilityLabel on the parent View with importantForAccessibility="yes-exclude-descendants" (Android) or accessibilityElementsHidden for children (iOS).
- Dynamic text (counts, time) — keep labels in sync with state.
- Contrast: use useColorScheme + design-system tokens.
Tools:
- eslint-plugin-react-native-a11y for lint warnings.
- iOS Accessibility Inspector (Xcode) for visual audits.