Thành phần ScrollView trong React Native là một vùng chứa cho phép cuộn nội dung vượt quá kích thước màn hình. Không giống như FlatList, ScrollView hiển thị toàn bộ nội dung cùng một lúc, phù hợp tối ưu cho lượng dữ liệu nhỏ, biểu mẫu và màn hình có chiều cao xác định. Theo React Native Docs, 2024, ScrollView hỗ trợ cuộn dọc và ngang, sự kiện onScroll, điều khiển vị trí theo chương trình và cử chỉ thu phóng. Thành phần này được hiển thị dưới dạng UIScrollView gốc trên iOS và ScrollView trên Android.
Những điểm chính
ScrollView là một thành phần React Native bao bọc nội dung của nó trong một vùng chứa có thể cuộn. Nếu nội dung vượt quá giới hạn màn hình, người dùng có thể cuộn theo chiều dọc hoặc ngang. ScrollView hiển thị tất cả các phần tử con khi gắn kết, bất kể chúng có hiển thị trên màn hình hay không.
Không giống như FlatList, chỉ hiển thị các phần tử hiển thị (hiển thị lười biếng), ScrollView tạo tất cả các khung nhìn gốc ngay lập tức. Điều này làm cho ScrollView thuận tiện cho các biểu mẫu, trang cài đặt, thẻ sản phẩm trên một màn hình — bất cứ nơi nào số lượng phần tử con nhỏ (tối đa 20-30) hoặc số lượng chính xác của chúng chưa được biết trước.
Theo React Native Using ScrollView, 2024, ScrollView hỗ trợ cuộn lồng nhau (ví dụ: ScrollView bên trong ScrollView), hiệu ứng nảy khi chạm đến cạnh, chỉ báo cuộn, định vị snap và xử lý cử chỉ. Trên iOS, ScrollView tự động thêm khoảng đệm SafeArea thông qua contentInsetAdjustmentBehavior.
ScrollView cung cấp một bộ thuộc tính phong phú để điều khiển hành vi cuộn, giao diện và tương tác. Hãy xem các nhóm chính: điều khiển cuộn, cài đặt trực quan, sự kiện và tính năng dành riêng cho nền tảng.
horizontal — chuyển hướng cuộn từ dọc (mặc định) sang ngang. scrollEnabled — vô hiệu hóa cuộn khi cần. showsVerticalScrollIndicator và showsHorizontalScrollIndicator kiểm soát việc hiển thị chỉ báo cuộn. bounces (iOS) bật/tắt hiệu ứng nảy khi chạm đến cạnh nội dung.
Sự kiện chính là onScroll, được kích hoạt mỗi lần cuộn và truyền một đối tượng với nativeEvent chứa contentOffset (vị trí hiện tại), contentSize (kích thước nội dung), layoutMeasurement (kích thước vùng hiển thị). onMomentumScrollEnd được kích hoạt sau khi cuộn quán tính hoàn tất. onScrollEndDrag — khi người dùng nhấc ngón tay khỏi màn hình. Những sự kiện này được sử dụng để triển khai cuộn vô hạn, hiệu ứng parallax và tải lười.
ScrollView cung cấp các phương thức để điều khiển theo chương trình qua ref: scrollTo({x, y, animated}) cuộn đến tọa độ chỉ định, scrollToEnd({animated}) — cuộn đến cuối nội dung, flashScrollIndicators() — tạm thời hiển thị các chỉ báo cuộn.
const scrollRef = useRef(null);
// Cuộn lên đầu
scrollRef.current.scrollTo({ x: 0, y: 0, animated: true });
// Cuộn đến cuối
scrollRef.current.scrollToEnd({ animated: true });
Điều khiển cuộn theo chương trình thường được sử dụng trong trò chuyện (tự động cuộn đến tin nhắn mới nhất), biểu mẫu (cuộn đến trường có lỗi) và băng chuyền (vuốt theo chương trình).
Việc chọn giữa ScrollView và FlatList là một trong những quyết định kiến trúc chính trong React Native. Cả hai thành phần đều cung cấp cuộn, nhưng sử dụng các chiến lược hiển thị khác nhau về cơ bản. ScrollView hiển thị mọi thứ cùng một lúc, FlatList — chỉ các phần tử hiển thị.
| Đặc điểm | ScrollView | FlatList |
|---|---|---|
| Hiển thị | Tất cả phần tử cùng lúc | Chỉ hiển thị + bộ đệm |
| Hiệu suất | Giảm với 30+ phần tử | Ổn định ở mọi số lượng |
| Nội dung | Mọi thành phần (biểu mẫu, thẻ) | Phần tử đồng nhất từ mảng |
| Kích thước dữ liệu | Nhỏ và vừa (tối đa 30 phần tử) | Lớn và không giới hạn |
| Cuộn ngang | Có (prop horizontal) | Có (horizontal) |
| Phần | Không (hiển thị như vốn có) | SectionList cho các phần |
Quy tắc chọn: ScrollView — cho màn hình có số lượng phần tử con đã biết và không vượt quá 20-30 (hồ sơ người dùng, biểu mẫu cài đặt, trang sản phẩm). FlatList — cho danh sách có khả năng nhiều phần tử (nguồn cấp tin tức, danh mục sản phẩm, tin nhắn trò chuyện). Nếu nội dung không đồng nhất (tiêu đề, biểu mẫu, thẻ, chân trang) — ScrollList được ưu tiên hơn vì FlatList mong đợi các phần tử đồng nhất.
ScrollView hỗ trợ cuộn ngang qua prop horizontal, làm cho nó lý tưởng cho băng chuyền, thư viện ảnh, tab và danh sách ngang. Khi kết hợp với prop pagingEnabled (iOS) hoặc snapToInterval, ScrollView trở thành thành phần cho điều hướng theo trang.
Thuộc tính horizontal thay đổi hướng cuộn. pagingEnabled (iOS) kích hoạt cuộn theo trang, nơi cuộn chỉ dừng ở ranh giới phần tử. snapToInterval đặt bước snap bằng pixel cho cả hai nền tảng.
const ImageCarousel = ({ images }) => (
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
onMomentumScrollEnd={handlePageChange}
>
{images.map((img, index) => (
<Image
key={index}
source={{ uri: img }}
style={{ width: SCREEN_WIDTH, height: 250 }}
/>
))}
</ScrollView>
);
Trong băng chuyền này, pagingEnabled tự động căn chỉnh cuộn theo ranh giới của mỗi hình ảnh. onMomentumScrollEnd cho phép cập nhật chỉ báo trang hiện tại. Băng chuyền như vậy chạy gốc và hỗ trợ cuộn quán tính.
Đối với các bước snap không chuẩn, hãy sử dụng snapToInterval (kích thước bước bằng pixel) và snapToAlignment (start, center, end). Với snapToOffsets, bạn có thể chỉ định một mảng các vị trí cụ thể để snap. Điều này hữu ích cho danh sách ngang với các thẻ có kích thước khác nhau.
Hãy xem xét hai kịch bản điển hình: màn hình có biểu mẫu (cuộn dọc) và danh sách danh mục ngang. Cả hai đều sử dụng ScrollView với các prop khác nhau để có hành vi tối ưu.
Trang chỉnh sửa hồ sơ chứa các phần tử không đồng nhất: hình đại diện, nhiều trường nhập liệu, công tắc và nút lưu. ScrollView cho phép cuộn toàn bộ trang cùng một lúc, thay vì từng khối riêng biệt.
const ProfileScreen = () => (
<ScrollView
contentContainerStyle={styles.container}
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
>
<AvatarPicker />
<TextInput placeholder="Name" />
<TextInput placeholder="Email" />
<TextInput placeholder="About me" multiline />
<SwitchRow label="Notifications" />
<Button title="Save" />
</ScrollView>
);
Prop keyboardShouldPersistTaps: 'handled' cho phép cuộn và tương tác với biểu mẫu khi bàn phím đang mở. contentContainerStyle áp dụng khoảng đệm cho tất cả nội dung. Mẫu này được sử dụng trong tất cả các màn hình biểu mẫu trong React Native.
Để điều hướng qua các danh mục (trò chuyện, bộ lọc, tab), một ScrollView ngang với các chip được sử dụng. Thành phần này thường thấy trong các ứng dụng thị trường và mạng xã hội.
const CategoryChips = ({ categories, selected, onSelect }) => (
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.chipContainer}
>
{categories.map((cat) => (
<Chip
key={cat.id}
label={cat.name}
isSelected={selected === cat.id}
onPress={() => onSelect(cat.id)}
/>
))}
</ScrollView>
);
ScrollView ngang với chỉ báo bị tắt là tiêu chuẩn cho các dải danh mục. Mỗi chip là một thành phần riêng biệt với trạng thái lựa chọn. Prop showsHorizontalScrollIndicator: false loại bỏ thanh cuộn, phù hợp với mong đợi của người dùng ứng dụng di động.
Câu hỏi thường gặp
ScrollView phù hợp cho lượng nhỏ dữ liệu (tối đa 20-30 phần tử) và nội dung không đồng nhất (biểu mẫu, hồ sơ, màn hình cài đặt). Chọn FlatList cho danh sách dài đồng nhất — nguồn cấp tin tức, danh mục sản phẩm, tin nhắn.
Sử dụng sự kiện onScroll với onScrollEndDrag hoặc onMomentumScrollEnd. Vị trí dọc hiện tại có trong nativeEvent.contentOffset.y. Để có hiệu suất, hãy sử dụng ScrollEventThrottle (iOS) để điều chỉnh tần suất gọi onScroll.
ScrollView hiển thị tất cả các phần tử khi gắn kết, tạo khung nhìn gốc cho mỗi phần tử. Với 50+ phần tử trên màn hình, bộ nhớ và luồng JS tăng lên, gây giảm khung hình. Trong những trường hợp như vậy, hãy sử dụng FlatList với hiển thị lười.
Đặt bounces={false}. Prop này chỉ hoạt động trên iOS và tắt hiệu ứng lò xo khi chạm đến cạnh ScrollView. Trên Android, không có hiệu ứng nảy theo mặc định, vì vậy prop này bị bỏ qua.
ScrollView không hỗ trợ cuộn vô hạn một cách gốc. Tuy nhiên, bạn có thể kết hợp onScroll với kiểm tra khoảng cách đến cạnh dưới (contentOffset.y + chiều cao màn hình >= contentSize.height) và thêm phần tử vào state. Đối với khối lượng lớn, hãy sử dụng FlatList với onEndReached.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm