Card cần gọn để người đọc lướt danh sách, nhưng phần mô tả không nên biến mất vĩnh viễn chỉ vì vượt hai dòng. Bạn có thể giới hạn số dòng ở trạng thái thu gọn và cho người dùng mở toàn bộ nội dung khi cần.
Bài đối chiếu React Native 0.88 ngày 03/11/2026. Demo được rà thủ công theo Text và accessibility props; hàm nhãn nút thuần JavaScript được chạy bằng Node 24.18.1. Chưa build React Native, chạy Hermes, VoiceOver, TalkBack hoặc đo số dòng trên thiết bị.
Rút gọn theo vùng hiển thị, không theo số ký tự
numberOfLines giới hạn số dòng sau khi Text được bố trí. ellipsizeMode chọn cách biểu thị phần bị rút gọn. Tài liệu hiện tại lưu ý trên Android, khi số dòng lớn hơn 1, chỉ tail hoạt động đúng; ví dụ vì vậy dùng tail.
Một số ký tự cố định không tương ứng số dòng cố định: font, cỡ chữ hệ thống, nội dung và chiều rộng đều ảnh hưởng. Giữ nguyên chuỗi nguồn rồi để Text thực hiện rút gọn giúp trạng thái mở rộng có thể dùng chính dữ liệu đầy đủ.
Demo với trạng thái mở rộng riêng
Đặt ví dụ trong App.jsx của project React Native thử:
import React, {useState} from 'react';
import {Pressable, StyleSheet, Text, View} from 'react-native';
const description =
'Card này có nội dung dài để minh họa việc rút gọn theo số dòng. ' +
'Bạn có thể mở toàn bộ mô tả, đọc phần còn lại rồi thu gọn về trạng thái ban đầu. ' +
'Chuỗi dữ liệu gốc vẫn được giữ nguyên trong cả hai trạng thái.';
function toggleLabel(expanded) {
return expanded ? 'Thu gọn' : 'Đọc tiếp';
}
export default function App() {
const [expanded, setExpanded] = useState(false);
return (
<View style={styles.screen}>
<View style={styles.card}>
<Text
style={styles.description}
numberOfLines={expanded ? undefined : 2}
ellipsizeMode="tail">
{description}
</Text>
<Pressable
style={styles.button}
accessibilityRole="button"
accessibilityState={{expanded}}
onPress={() => setExpanded(previous => !previous)}>
<Text style={styles.buttonText}>{toggleLabel(expanded)}</Text>
</Pressable>
</View>
</View>
);
}
const styles = StyleSheet.create({
screen: {flex: 1, justifyContent: 'center', padding: 16},
card: {width: '100%', maxWidth: 320, alignSelf: 'center', padding: 16},
description: {fontSize: 16, lineHeight: 24, color: '#0f172a'},
button: {marginTop: 8, paddingVertical: 12, alignSelf: 'flex-start'},
buttonText: {fontSize: 16, color: '#1d4ed8'},
});
Không có height cố định trên Text hoặc card, nên phần mở rộng không bị một giới hạn chiều cao do demo tự đặt che đi. Ở trạng thái mở, prop số dòng được bỏ qua bằng undefined. Callback dùng state trước đó để đảo trạng thái; chuỗi description không bị slice hoặc thay thế.
Kiểm tra hành vi trên nền tảng mục tiêu
Trên app thử, bắt đầu với trạng thái thu gọn, bấm Đọc tiếp rồi Thu gọn. Kiểm tra phần cuối mô tả có thể đọc được khi mở. Thử tăng cỡ chữ hệ thống, đổi chiều màn hình và dùng một câu có từ rất dài.
Không ghi một số dòng đo được trên thiết bị này thành kết quả cố định cho mọi máy. Mục tiêu là giới hạn tối đa khi thu gọn và có đường đọc đầy đủ, không phải bảo đảm một đoạn chuỗi cụ thể luôn nằm ở dòng thứ hai.
Nút demo luôn hiển thị, kể cả khi text đủ ngắn để không cần rút gọn. Nếu sản phẩm chỉ muốn nút xuất hiện khi thực sự tràn, cần đo và thiết kế logic bổ sung; bài này chưa triển khai phát hiện overflow bằng native event.
Trạng thái accessibility cũng cần được kiểm tra
accessibilityRole thể hiện đây là nút, còn accessibilityState.expanded phản ánh trạng thái hiện tại. Nhãn có chữ giúp hành động không phụ thuộc một icon không được mô tả. Đây là cấu hình theo API, chưa phải bằng chứng rằng toàn bộ trải nghiệm đọc đã đạt kiểm tra accessibility.
Hãy dùng VoiceOver và TalkBack để kiểm tra focus, nhãn và việc đọc nội dung sau khi mở rộng. Không tắt font scaling chỉ để card trông giống ảnh thiết kế. Với một mô tả quan trọng trong luồng giao dịch, có thể cần bố cục đọc đầy đủ ngay từ đầu thay vì bắt người dùng mở từng card.
Tránh hai nguồn dữ liệu không đồng nhất
Đừng tạo thêm chuỗi “mô tả ngắn” bằng cách cắt tùy ý rồi quên cập nhật khi dữ liệu gốc đổi. Nếu dữ liệu card thay từ bên ngoài, cần quyết định có thu gọn lại hay giữ trạng thái mở; demo cố định một nội dung nên chưa xử lý chính sách đổi item.
Tách dữ liệu, trạng thái mở và quy tắc layout giúp đoạn code dễ kiểm tra. Rút gọn có ích cho việc lướt, miễn là bạn vẫn giữ đường rõ ràng để người đọc tiếp cận nội dung đầy đủ.



