A performant, flicker-free sortable list component for React Native with drag-and-drop reordering
A performant, flicker-free sortable list component for React Native with drag-and-drop reordering capabilities.
- 🚀 Flicker-free reordering - Smooth animations with no visual glitches
- 📱 Native performance - Built with React Native Reanimated 2 and Gesture Handler
- 🎯 Precise drag detection - Long press to activate, smooth gesture handling
- 📍 Scroll position preservation - Maintains scroll position during reordering
- 🔄 State persistence - Survives component remounts and updates
- 🎨 Customizable rendering - Flexible item rendering with active state support
- 📏 Configurable item height - Consistent item heights for optimal performance
``bash`
yarn add react-native-sortable-drag-listor
npm install react-native-sortable-drag-list
This library requires the following peer dependencies:
`bash`
yarn add react-native-reanimated react-native-gesture-handleror
npm install react-native-reanimated react-native-gesture-handler
`tsx
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import { SortableList } from 'react-native-sortable-drag-list';
interface Item {
id: string;
title: string;
}
const MyComponent = () => {
const [items, setItems] = useState
{ id: '1', title: 'Item 1' },
{ id: '2', title: 'Item 2' },
{ id: '3', title: 'Item 3' },
]);
const renderItem = ({
item,
isActive,
}: {
item: Item;
isActive: boolean;
}) => (
);
return (
keyExtractor={(item) => item.id}
renderItem={renderItem}
itemHeight={70} // Optional: customize item height
onOrderChange={(newOrder) => {
const reorderedItems = newOrder.map((index) => items[index]);
setItems(reorderedItems);
}}
/>
);
};
`
| Prop | Type | Required | Description |
| --------------- | -------------------------------------------------------- | -------- | --------------------------------- |
| data | T[] | ✅ | Array of items to render |keyExtractor
| | (item: T, index: number) => string | ✅ | Function to extract unique keys |renderItem
| | (args: { item: T; isActive: boolean }) => ReactElement | ✅ | Function to render each item |onDragEnd
| | () => void | ❌ | Callback when drag operation ends |onOrderChange
| | (newOrder: number[]) => void | ❌ | Callback when order changes |itemHeight
| | number | ❌ | Height of each item (default: 70) |
| Prop | Type | Required | Description |
| ------------- | ---------------------------------------------------------- | -------- | --------------------------------- |
| item | T | ✅ | The item data |index
| | number | ✅ | Visual index in the list |dataLength
| | number | ✅ | Total number of items |renderItem
| | (params: { item: T; isActive: boolean }) => ReactElement | ✅ | Item renderer |activeIndex
| | SharedValue | ✅ | Currently active item index |fromSlot
| | SharedValue | ✅ | Starting position of dragged item |targetSlot
| | SharedValue | ✅ | Target position of dragged item |onDragStart
| | () => void | ✅ | Drag start callback |onDragEnd
| | (payload: { from: number; to: number }) => void | ✅ | Drag end callback |
`tsx`
// Pass custom item height directly to SortableList
keyExtractor={(item) => item.id}
renderItem={renderItem}
itemHeight={100} // Custom height instead of default 70
onOrderChange={(newOrder) => {
const reorderedItems = newOrder.map((index) => items[index]);
setItems(reorderedItems);
}}
/>
`tsx
const MyComponent = () => {
const [items, setItems] = useState(/ ... /);
return (
keyExtractor={(item) => item.id}
renderItem={renderItem}
onOrderChange={(newOrder) => {
// The component automatically preserves scroll position
// during reordering operations
setItems(newOrder.map((index) => items[index]));
}}
onDragEnd={() => {
// Optional: Perform actions when drag ends
console.log('Drag operation completed');
}}
/>
);
};
`
`tsx
import { View, Text } from 'react-native';
import Animated from 'react-native-reanimated';
const renderItem = ({ item, isActive }: { item: Item; isActive: boolean }) => (
styles.item,
isActive && styles.activeItem,
// Add custom animations based on isActive
]}
>
{isActive &&
);
`
- Hardware acceleration - Uses renderToHardwareTextureAndroid for smooth animations
- Offscreen compositing - Prevents visual artifacts during complex animations
- Stable keys - Maintains React reconciliation efficiency
- Shared values - Efficient state management with Reanimated
- Gesture optimization - Minimal gesture detection overhead
This library is designed for React Native and does not support web browsers.
1. Fork the repository
2. Create your feature branch (git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature'
3. Commit your changes ()git push origin feature/amazing-feature`)
4. Push to the branch (
5. Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Initial release
- Flicker-free drag and drop reordering
- Scroll position preservation
- State persistence across remounts
- Hardware acceleration support