Use <SkiaFlatList /> as a high-performance replacement for the standard React Native <FlatList />. It leverages the Skia Rendering Engine, which means you cannot use standard React Native components inside it; instead, you must use Skia drawing primitives.
Key Requirements
- Layout Calculation: You must manually calculate or provide the layout and dimensions of your list items. For text, you can use Skia's
measureText() or the Paragraph getHeight() API. - Worklets: Functions like
transformItem and renderItem must be marked with the "worklet" directive to run on the Skia thread. - Data Serialization: The
initialData prop should return an array that can be serialized and passed to the worklet thread.
Core Props
initialData: A function returning the initial array of data.transformItem: A worklet function called once per item during the initial mount to transform the raw data into a Skia-compatible object.renderItem: A worklet function called whenever an item's visibility changes. It is responsible for calculating the item's height and adding Skia nodes to the provided element.
import { Skia } from "@shopify/react-native-skia";
import { SkiaFlatList } from "react-native-skia-list";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const paragraphBuilder = Skia.ParagraphBuilder.Make({
textStyle: {
color: Skia.Color("black"),
fontSize: 20,
},
});
export default function MyList() {
const safeArea = useSafeAreaInsets();
return (
<SkiaFlatList
safeArea={safeArea}
initialData={() => [0, 1, 2, 3, 4, 5, 6, 7, 8]}
transformItem={(item, index, id, state) => {
"worklet";
paragraphBuilder.reset();
return paragraphBuilder.addText(`Item ${item}`).build();
}}
renderItem={(item, index, state, element) => {
"worklet";
const { width } = state.layout.value;
item.layout(width);
const height = item.getHeight();
if (!element) return height;
element.addChild(
SkiaDomApi.ParagraphNode({
paragraph: item,
x: 0,
y: 0,
width,
}),
);
return height;
}}
/>
);
}