SectionList
là một thành phần mạnh mẽ trong React Native, được sử dụng để hiển thị danh sách các mục được nhóm lại theo các phần (sections). Mỗi phần có thể có một tiêu đề riêng và chứa nhiều mục con. SectionList
rất hữu ích khi bạn cần hiển thị dữ liệu có cấu trúc phân cấp, chẳng hạn như danh sách liên lạc, danh sách sản phẩm theo danh mục, hoặc lịch trình sự kiện theo ngày. Trong bài viết này, chúng ta sẽ tìm hiểu chi tiết về cách sử dụng SectionList
, các thuộc tính quan trọng, và các kỹ thuật tối ưu hóa, cùng với các ví dụ cụ thể.
Cú Pháp Cơ Bản
Để sử dụng SectionList
trong React Native, bạn cần import nó từ thư viện react-native
và sử dụng nó như một thành phần trong ứng dụng của bạn.
javascript
import React from "react";
import { SectionList, View, Text, StyleSheet } from "react-native";
const sections = [
{ title: "A", data: ["Apple", "Avocado"] },
{ title: "B", data: ["Banana", "Blueberry"] },
{ title: "C", data: ["Cherry", "Coconut"] },
];
const App = () => {
return (
<View style={styles.container}>
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
item: {
padding: 20,
fontSize: 18,
height: 44,
},
header: {
fontSize: 24,
backgroundColor: "#f4f4f4",
padding: 10,
},
});
export default App;
Các Thuộc Tính Quan Trọng của SectionList
sections
Thuộc tính sections
xác định nguồn dữ liệu cho SectionList
. Đây là một mảng các đối tượng, mỗi đối tượng đại diện cho một phần và chứa một tiêu đề và một mảng dữ liệu.
Ví dụ:
javascript
const sections = [
{ title: "A", data: ["Apple", "Avocado"] },
{ title: "B", data: ["Banana", "Blueberry"] },
{ title: "C", data: ["Cherry", "Coconut"] },
];
renderItem
Thuộc tính renderItem
xác định cách mỗi mục trong danh sách được hiển thị. Nó nhận một đối tượng chứa mục dữ liệu và trả về một thành phần React để hiển thị mục đó.
Ví dụ:
javascript
const renderItem = ({ item }) => <Text style={styles.item}>{item}</Text>;
renderSectionHeader
Thuộc tính renderSectionHeader
xác định cách tiêu đề của mỗi phần được hiển thị. Nó nhận một đối tượng chứa tiêu đề của phần và trả về một thành phần React để hiển thị tiêu đề đó.
Ví dụ:
javascript
const renderSectionHeader = ({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
);
keyExtractor
Thuộc tính keyExtractor
xác định cách lấy khóa duy nhất cho mỗi mục trong danh sách. Điều này giúp React Native xác định các mục nào cần được cập nhật.
Ví dụ:
javascript
const keyExtractor = (item, index) => item + index;
horizontal
Thuộc tính horizontal
xác định liệu SectionList
có cuộn theo chiều ngang hay không. Mặc định là false
.
Ví dụ:
javascript
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
horizontal
/>
onEndReached
Thuộc tính onEndReached
là một hàm callback được gọi khi người dùng cuộn đến cuối danh sách. Điều này thường được sử dụng để tải thêm dữ liệu.
Ví dụ:
javascript
const loadMoreData = () => {
// Tải thêm dữ liệu
};
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
onEndReached={loadMoreData}
onEndReachedThreshold={0.5}
/>;
refreshing và onRefresh
Thuộc tính refreshing
xác định liệu danh sách có đang được làm mới hay không, và onRefresh
là một hàm callback được gọi khi người dùng kéo để làm mới danh sách.
Ví dụ:
javascript
const [refreshing, setRefreshing] = useState(false);
const onRefresh = () => {
setRefreshing(true);
// Làm mới dữ liệu
setTimeout(() => {
setRefreshing(false);
}, 2000);
};
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
refreshing={refreshing}
onRefresh={onRefresh}
/>;
Ví Dụ Chi Tiết về SectionList
Ví Dụ 1: Tạo SectionList Cơ Bản
javascript
import React from "react";
import { SectionList, View, Text, StyleSheet } from "react-native";
const sections = [
{ title: "A", data: ["Apple", "Avocado"] },
{ title: "B", data: ["Banana", "Blueberry"] },
{ title: "C", data: ["Cherry", "Coconut"] },
];
const App = () => {
return (
<View style={styles.container}>
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
item: {
padding: 20,
fontSize: 18,
height: 44,
},
header: {
fontSize: 24,
backgroundColor: "#f4f4f4",
padding: 10,
},
});
export default App;
Ví Dụ 2: Tạo SectionList với Màu Sắc Tùy Chỉnh
javascript
import React from "react";
import { SectionList, View, Text, StyleSheet } from "react-native";
const sections = [
{ title: "A", data: ["Apple", "Avocado"] },
{ title: "B", data: ["Banana", "Blueberry"] },
{ title: "C", data: ["Cherry", "Coconut"] },
];
const App = () => {
return (
<View style={styles.container}>
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<Text style={styles.item}>{item}</Text>
</View>
)}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
itemContainer: {
backgroundColor: "#f9c2ff",
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
item: {
fontSize: 18,
},
header: {
fontSize: 24,
backgroundColor: "#f4f4f4",
padding: 10,
},
});
export default App;
Ví Dụ 3: Tạo SectionList với Chức Năng Kéo Để Làm Mới
javascript
import React, { useState } from "react";
import {
SectionList,
View,
Text,
StyleSheet,
RefreshControl,
} from "react-native";
const sections = [
{ title: "A", data: ["Apple", "Avocado"] },
{ title: "B", data: ["Banana", "Blueberry"] },
{ title: "C", data: ["Cherry", "Coconut"] },
];
const App = () => {
const [refreshing, setRefreshing] = useState(false);
const onRefresh = () => {
setRefreshing(true);
// Làm mới dữ liệu
setTimeout(() => {
setRefreshing(false);
}, 2000);
};
return (
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<Text style={styles.item}>{item}</Text>
</View>
)}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
/>
);
};
const styles = StyleSheet.create({
itemContainer: {
backgroundColor: "#f9c2ff",
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
item: {
fontSize: 18,
},
header: {
fontSize: 24,
backgroundColor: "#f4f4f4",
padding: 10,
},
});
export default App;
Các Kỹ Thuật Tối Ưu Hóa SectionList
Sử Dụng keyExtractor
Sử dụng keyExtractor
để cung cấp khóa duy nhất cho mỗi mục trong danh sách, giúp React Native xác định các mục nào cần được cập nhật.
Ví dụ:
javascript
const keyExtractor = (item, index) => item + index;
Tránh Sử Dụng Hàm Inline
Tránh sử dụng các hàm inline cho thuộc tính renderItem
và renderSectionHeader
để tránh việc tạo lại hàm mỗi khi component được render.
Ví dụ:
javascript
const renderItem = ({ item }) => <Text style={styles.item}>{item}</Text>;
const renderSectionHeader = ({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
);
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
/>;
Sử Dụng getItemLayout
Nếu tất cả các mục trong danh sách có cùng chiều cao, sử dụng thuộc tính getItemLayout
để tối ưu hóa hiệu suất cuộn.
Ví dụ:
javascript
const ITEM_HEIGHT = 44;
const getItemLayout = (data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
});
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
getItemLayout={getItemLayout}
/>;
Sử Dụng PureComponent hoặc React.memo
Sử dụng PureComponent
hoặc React.memo
để tránh việc render lại không cần thiết của các mục trong danh sách.
Ví dụ:
javascript
import React, { memo } from "react";
import { View, Text, StyleSheet } from "react-native";
const Item = memo(({ text }) => (
<View style={styles.itemContainer}>
<Text style={styles.item}>{text}</Text>
</View>
));
const renderItem = ({ item }) => <Item text={item.text} />;
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
/>;
Các Hạn Chế của SectionList Component
Mặc dù SectionList
component trong React Native rất mạnh mẽ, nhưng nó cũng có một số hạn chế:
- Hiệu Suất: Khi sử dụng quá nhiều
SectionList
lồng nhau, hiệu suất của ứng dụng có thể bị ảnh hưởng. - Khả Năng Tái Sử Dụng: Việc sử dụng inline styles có thể làm giảm khả năng tái sử dụng các thành phần.
- Quản Lý Sự Kiện:
SectionList
không hỗ trợ tất cả các sự kiện như các thành phần khác, ví dụ như sự kiện hover.
Kết Luận
SectionList
là một thành phần cơ bản và quan trọng trong React Native, giúp bạn tạo ra các giao diện người dùng mượt mà và hiệu quả. Bằng cách hiểu rõ các thuộc tính và cách sử dụng SectionList
, bạn có thể tạo ra các giao diện người dùng mượt mà và hiệu quả. Hy vọng qua bài viết này, bạn đã có thể nắm bắt được cách sử dụng SectionList
trong React Native và áp dụng vào các dự án của mình.