-
Notifications
You must be signed in to change notification settings - Fork 32
Open
Description
Description
When dragging and dropping an item to reorder it, there's a visual glitch where the item briefly "jumps" back to its original position before settling into the new position. This creates a jarring user experience.
Expected Behavior
When I drop an item at a new position, it should smoothly stay in that position without any visual jump or animation back to the original position.
Actual Behavior
- User drags an item from position A to position B
- User releases the item at position B
- The item briefly animates/jumps back to position A
- Then the item appears at position B (the correct final position)
Environment
- react-native-draglist version: 3.10.0
- React Native version: 0.81.4
- Platform: iOS and Android
Code Example
import React, { useCallback, useMemo } from 'react';
import { View, Text } from 'react-native';
import DragList from 'react-native-draglist';
import { useAppDispatch, useAppSelector } from '../../../hooks/redux';
import { setCategoryReordering } from '../../../store/reducer/mediaSlice';
function Content({ screen }) {
const dispatch = useAppDispatch();
const state = useAppSelector(state => state.media.mediaData.movie);
const data = useMemo(() => {
if (!state?.keys?.length) {
return [];
}
return state.keys.reduce((acc, key) => {
const hasContents =
Array.isArray(state[key]?.contents) && state[key].contents.length > 0;
const isRejected = rejectedKeys.includes(key);
const info = state[key]?.category_info;
if (!hasContents || isRejected || !info) {
return acc;
}
acc.push({
id: info.category_id,
category_name: info.category_name,
category_id: info.category_id,
count: state[key].contents.length,
});
return acc;
}, []);
}, [state, rejectedKeys]);
const onReordered = useCallback(
async (fromIndex, toIndex) => {
const copy = [...data];
const [movedItem] = copy.splice(fromIndex, 1);
copy.splice(toIndex, 0, movedItem);
const updatedState = [
...rejectedKeys,
...copy.map(item => item.category_id),
];
dispatch(
setCategoryReordering({
mediaType: 'movie',
orderedKeys: updatedState,
}),
);
},
[data, rejectedKeys, dispatch],
);
const renderItem = useCallback(
({ item, onDragStart, onDragEnd, isActive }) => {
return (
<TouchableOpacity
activeOpacity={0.8}
onPress={onPress}
onLongPress={onDragStart}
onPressOut={onDragEnd}
delayLongPress={200}
>
<View style={styles.categoryBtnContent}>
<Text style={styles.categoryName} numberOfLines={1}>
{displayText}
</Text>
<SIX_POIN_ICON color={APP_DEFAULT_BRANDING.white} />
</View>
</TouchableOpacity>
);
},
[],
);
const keyExtractor = useCallback(item => item?.category_id?.toString(), []);
return (
<DragList
data={data}
keyExtractor={keyExtractor}
renderItem={renderItem}
onReordered={onReordered}
showsVerticalScrollIndicator={false}
/>
);
}Video Demonstration
https://drive.google.com/file/d/11j5Mvtlq-wgVgJUAxGU4RNDkqSA2QL1Z/view?usp=sharing
airo-email
Metadata
Metadata
Assignees
Labels
No labels