gusgard / react-native-swiper-flatlist

👆 Swiper component implemented with FlatList using Hooks & Typescript + strict automation tests with Detox
Apache License 2.0
511 stars 95 forks source link

The index will jump to 0 on expo SDK 48 #164

Closed felixliu226 closed 1 year ago

felixliu226 commented 1 year ago

I just updated my project to expo SDK 48. And for the swiper flatlist with a given start index, it will jump to 0 immediately. I checked, the onChangeIndex will be called immediately when the list is rendered.

React Native version: 0.71.4

Steps To Reproduce

  1. Create an emtpy project with expo SDK 48
  2. copy code from sample and run You may refer to this snack, but it is based on expo SDK 47 and works as expected, but when tried on SDK 48, it just jump to index 0. https://snack.expo.dev/@felixliu_labviso/react-native-swiper-flatlist

Describe what you expected to happen: The list should be stay in the destinated index instead of jumping to index 0.

Snack, code example, screenshot, or link to a repository: This snack is based on expo SDK 47 and works as expected, but when tried on SDK 48, it just jump to index 0. https://snack.expo.dev/@felixliu_labviso/react-native-swiper-flatlist

Keylekan commented 1 year ago

I had the same issue, I fixed it by setting getItemLayout. By the way the documentation of FlatList explicitely specify that initialScrollIndex requires getItemLayout (https://reactnative.dev/docs/flatlist#initialscrollindex), and the index prop of SwiperFlatList is passed through initialScrollIndex prop of FlatList.

Here is my piece of code (note that I use a useEffect to keep index when orientation changes) :

const ref = useRef<SwiperFlatList>(null);
const { width } = useWindowDimensions();

useEffect(() => ref.current?.scrollToIndex({ index: ref.current.getCurrentIndex() }), [width]);

return (
    <SwiperFlatList
        ref={ref}
        index={initialIndex}
        getItemLayout={(__data, ItemIndex: number) => ({
            length: width,
            offset: width * ItemIndex,
            index: ItemIndex,
        })}
        data={data}
        renderItem={({ item }) => (
            // ...
        )}
        keyExtractor={(item): string => item}
        useReactNativeGestureHandler
        windowSize={5}
        keyboardShouldPersistTaps="handled"
    />
);
felixliu226 commented 1 year ago

I had the same issue, I fixed it by setting getItemLayout. By the way the documentation of FlatList explicitely specify that initialScrollIndex requires getItemLayout (https://reactnative.dev/docs/flatlist#initialscrollindex), and the index prop of SwiperFlatList is passed through initialScrollIndex prop of FlatList.

Here is my piece of code (note that I use a useEffect to keep index when orientation changes) :

const ref = useRef<SwiperFlatList>(null);
const { width } = useWindowDimensions();

useEffect(() => ref.current?.scrollToIndex({ index: ref.current.getCurrentIndex() }), [width]);

return (
    <SwiperFlatList
        ref={ref}
        index={initialIndex}
        getItemLayout={(__data, ItemIndex: number) => ({
            length: width,
            offset: width * ItemIndex,
            index: ItemIndex,
        })}
        data={data}
        renderItem={({ item }) => (
            // ...
        )}
        keyExtractor={(item): string => item}
        useReactNativeGestureHandler
        windowSize={5}
        keyboardShouldPersistTaps="handled"
    />
);

Thanks, it works!

gusgard commented 1 year ago

It should be fixed in 3.2.0, could you test it? @felixliu226 @Keylekan

felixliu226 commented 1 year ago

It should be fixed in 3.2.0, could you test it? @felixliu226 @Keylekan

Thanks! just tried with 3.2.2 and it works.