SectionList
React Native 在 FlatList
的基础上提供了一个便捷组件,称为 SectionList
。该组件有一些额外的属性
FlashList
不提供这些属性,但是所有这些属性都可以用现有的属性替换。
从 SectionList
迁移到 FlashList
的难度取决于你手头的数据——数据可能更适合 SectionList
,需要你对数据进行处理,但反之亦然。 在这种情况下,使用 FlashList
而不是 SectionList
甚至可能会减少代码量。
让我们通过以下示例(一个联系人列表)了解如何从 SectionList
迁移到 FlashList
。
以下是我们如何使用 SectionList
编写这样的列表
import React from "react";
import { SectionList, StyleSheet, Text } from "react-native";
interface Contact {
firstName: string;
lastName: string;
}
interface Section {
title: string;
data: Contact[];
}
const contacts: Section[] = [
{ title: "A", data: [{ firstName: "John", lastName: "Aaron" }] },
{
title: "D",
data: [
{ firstName: "John", lastName: "Doe" },
{ firstName: "Mary", lastName: "Dianne" },
],
},
];
const ContactsSectionList = () => {
return (
<SectionList
sections={contacts}
renderItem={({ item }) => {
return <Text>{item.firstName}</Text>;
}}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
/>
);
};
const styles = StyleSheet.create({
header: {
fontSize: 32,
backgroundColor: "#fff",
},
});
要迁移到 FlashList
,我们需要首先将 contacts
变量转换为以下形式
const contacts: (string | Contact)[] = [
"A",
{ firstName: "John", lastName: "Aaron" },
"D",
{ firstName: "John", lastName: "Doe" },
{ firstName: "Mary", lastName: "Dianne" },
];
如你所见,你可以将 section 项目与数据一起添加。然后在 renderItem
中,你可以根据项目的类型来区分渲染什么
const ContactsFlashList = () => {
return (
<FlashList
data={contacts}
renderItem={({ item }) => {
if (typeof item === "string") {
// Rendering header
return <Text style={styles.header}>{item}</Text>;
} else {
// Render item
return <Text>{item.firstName}</Text>;
}
}}
getItemType={(item) => {
// To achieve better performance, specify the type based on the item
return typeof item === "string" ? "sectionHeader" : "row";
}}
estimatedItemSize={100}
/>
);
};
你可以为 SectionList
的其余属性遵循与 renderItem
类似的模式。
如果你希望你的 section header 具有粘性,你还需要计算 stickyHeaderIndices
的数组
const stickyHeaderIndices = contacts
.map((item, index) => {
if (typeof item === "string") {
return index;
} else {
return null;
}
})
.filter((item) => item !== null) as number[];
就是这样!下面你可以找到 FlashList
的完整示例
import React from "react";
import { StyleSheet, Text } from "react-native";
import { FlashList } from "@shopify/flash-list";
interface Contact {
firstName: string;
lastName: string;
}
const contacts: (string | Contact)[] = [
"A",
{ firstName: "John", lastName: "Aaron" },
"D",
{ firstName: "John", lastName: "Doe" },
{ firstName: "Mary", lastName: "Dianne" },
];
const stickyHeaderIndices = contacts
.map((item, index) => {
if (typeof item === "string") {
return index;
} else {
return null;
}
})
.filter((item) => item !== null) as number[];
const ContactsFlashList = () => {
return (
<FlashList
data={contacts}
renderItem={({ item }) => {
if (typeof item === "string") {
// Rendering header
return <Text style={styles.header}>{item}</Text>;
} else {
// Render item
return <Text>{item.firstName}</Text>;
}
}}
stickyHeaderIndices={stickyHeaderIndices}
getItemType={(item) => {
// To achieve better performance, specify the type based on the item
return typeof item === "string" ? "sectionHeader" : "row";
}}
estimatedItemSize={100}
/>
);
};
const styles = StyleSheet.create({
header: {
fontSize: 32,
backgroundColor: "#fff",
},
});