Skip to content

Commit d508f85

Browse files
committed
Fix autoplay timing by stabilizing _scrollToIndex and processing all viewability changes
Two issues caused unreliable autoplay behavior: 1. _scrollToIndex was recreated on every prevIndex change (via its dependency on currentIndexes.index and currentIndexes.prevIndex). Since it was in the autoplay useEffect dependency array, this caused unnecessary timer resets whenever _onViewableItemsChanged updated prevIndex during scroll animations. Fix: use functional state updater so _scrollToIndex has an empty dependency array and remains a stable reference. 2. _onViewableItemsChanged only processed the first item in the changed array. When FlatList reported multiple viewability changes simultaneously (e.g., one item becoming non-viewable and another becoming viewable), the second change was silently dropped. Fix: iterate over all changed items with forEach to ensure correct index tracking. https://claude.ai/code/session_012WFS8zGREtMjNNj9NECCVw
1 parent 16fb10e commit d508f85

1 file changed

Lines changed: 23 additions & 30 deletions

File tree

src/components/SwiperFlatList/SwiperFlatList.tsx

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -102,32 +102,24 @@ export const createSwiperFlatList = (FlatListComponent: typeof RNFlatList) =>
102102
[onChangeIndex],
103103
);
104104

105-
const _scrollToIndex = React.useCallback(
106-
(params: ScrollToIndex) => {
107-
const { index: indexToScroll, animated = true } = params;
108-
const newParams = { animated, index: indexToScroll };
105+
const _scrollToIndex = React.useCallback((params: ScrollToIndex) => {
106+
const { index: indexToScroll, animated = true } = params;
109107

110-
setIgnoreOnMomentumScrollEnd(true);
108+
setIgnoreOnMomentumScrollEnd(true);
111109

112-
const next = {
113-
index: indexToScroll,
114-
prevIndex: currentIndexes.index,
115-
};
116-
if (currentIndexes.index !== next.index && currentIndexes.prevIndex !== next.prevIndex) {
117-
setCurrentIndexes({ index: next.index, prevIndex: next.prevIndex });
118-
} else if (currentIndexes.index !== next.index) {
119-
setCurrentIndexes((prevState) => ({ ...prevState, index: next.index }));
120-
} else if (currentIndexes.prevIndex !== next.prevIndex) {
121-
setCurrentIndexes((prevState) => ({ ...prevState, prevIndex: next.prevIndex }));
110+
setCurrentIndexes((prevState) => {
111+
const newState = { index: indexToScroll, prevIndex: prevState.index };
112+
if (prevState.index === newState.index && prevState.prevIndex === newState.prevIndex) {
113+
return prevState;
122114
}
115+
return newState;
116+
});
123117

124-
// When execute "scrollToIndex", we ignore the method "onMomentumScrollEnd"
125-
// because it not working on Android
126-
// https://github.com/facebook/react-native/issues/21718
127-
flatListElement?.current?.scrollToIndex(newParams);
128-
},
129-
[currentIndexes.index, currentIndexes.prevIndex],
130-
);
118+
// When execute "scrollToIndex", we ignore the method "onMomentumScrollEnd"
119+
// because it not working on Android
120+
// https://github.com/facebook/react-native/issues/21718
121+
flatListElement?.current?.scrollToIndex({ animated, index: indexToScroll });
122+
}, []);
131123

132124
// change the index when the user swipe the items
133125
React.useEffect(() => {
@@ -216,15 +208,16 @@ export const createSwiperFlatList = (FlatListComponent: typeof RNFlatList) =>
216208
>(
217209
() => (params) => {
218210
const { changed } = params;
219-
const newItem = changed?.[FIRST_INDEX];
220-
if (newItem !== undefined) {
221-
const nextIndex = newItem.index as number;
222-
if (newItem.isViewable) {
223-
setCurrentIndexes((prevState) => ({ ...prevState, index: nextIndex }));
224-
} else {
225-
setCurrentIndexes((prevState) => ({ ...prevState, prevIndex: nextIndex }));
211+
changed?.forEach((newItem) => {
212+
if (newItem.index != null) {
213+
const nextIndex = newItem.index as number;
214+
if (newItem.isViewable) {
215+
setCurrentIndexes((prevState) => ({ ...prevState, index: nextIndex }));
216+
} else {
217+
setCurrentIndexes((prevState) => ({ ...prevState, prevIndex: nextIndex }));
218+
}
226219
}
227-
}
220+
});
228221
onViewableItemsChanged?.(params);
229222
},
230223
[onViewableItemsChanged],

0 commit comments

Comments
 (0)