SectionList base on FlashList
npm install flash-section-listThe library, which is dependent on @shopify/flash-list, overrides the overrideItemLayout function internally to ensure that sections with different numOfColumns are rendered properly.
Additionally, for enhanced performance, the library also overrides the getItemType function internally based on the type information of the section and the header or footer.
You can set sticky properties not only for section items but also for footers or headers.
``ts
interface ElementSection {
element: React.ReactElement | null;
sticky?: boolean;
type?: string;
size?: number;
}
interface DataSection
data: ItemT[];
renderItem: ListRenderItem
type?: string; // <- default: sectionIndex
header?: ElementSection;
footer?: ElementSection;
stickyHeaderIndices?: number[];
numOfColumns?: number;
itemSize?: number;
gap?: number;
}
`
https://github.com/JoonDong2/flash-section-list-example
`sh`
npm install @shopify/flash-list flash-section-list
`js
import FlashSectionList, { type Section } from 'flash-section-list';
import { Dimensions, View } from 'react-native';
const screenWidth = Dimensions.get('screen').width;
`
!demo
`js`
export default function App() {
return
}
The type of a Section refers to the type that will be applied to all items, excluding the header and footer.
By default, the index of the Section is used. However, if items in different Sections share the same type, you may use the same type for them. (e.g., Example)
It's recommended to use the same type for items with the same structure to encourage optimal reuse.
You can use the methods exposed by FlashList, and additionally, the scrollToSection method is available.
`js
import FlashSectionList, { type FlashSectionListHandle } from 'flash-section-list';
import { useRef, useEffect } from 'react';
export default function App() {
const ref = useRef
useEffect(() => {
setTimetout(() => {
ref.current?.scrollToSection({ sectionIndex: 1 });
}, 1000);
}, []);
return (
);
}
`
The data for each section may differ, and the type of the item property in each section's renderItem cannot be inferred correctly.
Therefore, you must manually cast the types.
`js
interface Item {
id: number;
}
const sections =[{
data: Array.from({length: 10}).map((_, index) => ({id: index})),
renderItem: ({item}: {item: Item}) =>
}]
`
This library parses the sections array whenever it changes.
Therefore, you should avoid changing the sections array.
When numOfColumns is set to 3 and there are 5 items, an empty space will occur in the second row.
If this empty space is not physically filled, the next row will move up, causing an alignment issue.
To resolve this, I wrap the item with a View and use the onLayout of that View to calculate the size of the blank space.
To fully take advantage of reusability, I didn't limit the wrapping to just the last item.
As a result, in each section, item heights must be the same in vertical list. (The opposite applies for horizontal list)
There is sometimes an issue in the iPhone simulator where the screen shakes when scrolling to the edges.
This issue was not observed on the Android emulator, or on actual iPhone and Android devices.
This library can be used withreact-native-observable-list to observe the visibility of items.
`js
import {Dimensions, View} from 'react-native';
import {
type Section,
FlashSectionListBuilder,
} from 'flash-section-list';
import {observe, useInViewPort} from 'react-native-observable-list';
const screenWidth = Dimensions.get('screen').width;
const builder = FlashSectionListBuilder();
const ObservableList = observe(FlashList);
builder.setFlashList(ObservableList);
const ObservableFlashSectionList = builder.build();
const Header = () => {
useInViewPort(() => {
console.log('visible');
return () => {
console.log('disappear');
};
}, []);
return
};
const sections: Section[] = [
{
header:
// data, renderItem, ...
},
// or
{
element:
}
]
`
flash-list internally sets the forceNonDeterministicRendering property of recyclerlistview to true.
Because of this property, the layout of the items is recalculated every time, so the size and position of the scroll indicator are unstable.
To solve this problem, you can use the size and itemSize properties of Section.
The size is applied to the height in a vertical list, or to the width` in a horizontal list.
MIT
---
Made with create-react-native-library