For full control over layout and behavior, use the low-level primitives. This pattern works with any list component like FlatList, FlashList, LegendList, or ScrollView.
Core Primitives
useSortableList: A hook that manages reorder state and provides the necessary props to wire up a list.SortableContainer: A wrapper for the list component that handles monitoring and auto-scrolling.SortableItem: A wrapper for individual cells that handles shift animations.
Wiring Requirements
To make a list sortable using this pattern, you must wire the following from the sortable object to your list component:
sortable.data: The current state of the data.sortable.stableKeyExtractor: The key extractor for the list.sortable.onScroll: The scroll handler.sortable.onContentSizeChange: The content size change handler.sortable.onReorder: The reorder callback to update your state.
import { useState, useRef } from 'react';
import { FlatList, Text, View, StyleSheet } from 'react-native';
import {
DraxProvider,
useSortableList,
SortableContainer,
SortableItem,
} from 'react-native-drax';
function App() {
const [items, setItems] = useState(['A', 'B', 'C', 'D', 'E']);
const listRef = useRef<FlatList>(null);
const sortable = useSortableList({
data: items,
keyExtractor: (item) => item,
onReorder: ({ data }) => setItems(data),
});
return (
<DraxProvider>
<SortableContainer sortable={sortable} scrollRef={listRef}>
<FlatList
ref={listRef}
data={sortable.data}
keyExtractor={sortable.stableKeyExtractor}
onScroll={sortable.onScroll}
onContentSizeChange={sortable.onContentSizeChange}
renderItem={({ item, index }) => (
<SortableItem sortable={sortable} index={index}>
<View style={styles.item}>
<Text>{item}</Text>
</View>
</SortableItem>
)}
/>
</SortableContainer>
</DraxProvider>
);
}
const styles = StyleSheet.create({
item: {
padding: 16,
backgroundColor: '#eee',
margin: 4,
borderRadius: 8,
},
});