dohooo / react-native-reanimated-carousel

🎠 React Native swiper/carousel component, fully implemented using reanimated v2, support to iOS/Android/Web. (Swiper/Carousel)
https://react-native-reanimated-carousel.vercel.app
MIT License
2.85k stars 329 forks source link

Using windowSize and changing orientation causes items not to render #633

Open MetaBenji opened 5 months ago

MetaBenji commented 5 months ago

Describe the bug A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!

To Reproduce Steps to reproduce the behavior:

  1. Set windowSize to any number less than the length of your data array
  2. Change the orientation of your device
  3. Swipe through some slides
  4. You'll see some of the slides are not rendered

Expected behavior All of the slides to render

Screenshots IMG_64BAA06F1AE3-1

Versions (please complete the following information):

Smartphone (please complete the following information):

Additional context

Note in the snippet below, the width and height props are changing when the screen orientation changes. I wonder if that is having an impact?

Code snippets:

  export const FeaturedCarousel = memo(function FeaturedCarousel() {
  const [currentSlide, setCurrentSlide] = useState(0)
  const carouselRef = useRef<ICarouselInstance>(null)

  const { width: carouselWidth } = useWindowDimensions()
  const carouselQuery = useGetFeaturedCarouselQuery()

  const carouselHeight = Math.min(carouselWidth * CAROUSEL_HEIGHT_MULTIPLIER, FEATURED_CAROUSEL_MAX_HEIGHT)

  const slides = useMemo(() => carouselQuery.data?.filter((item) => !item.hideInMobile), [carouselQuery.data])

  const [isAutoSlideActive, setIsAutoSlideActive] = useBoolean(true)

  const onVideoEnd = useCallback(() => {
    isAutoSlideActive && carouselRef.current?.next()
  }, [isAutoSlideActive])

  const renderItem = useCallback(
    ({ item, index }: { item: FeaturedCarouselItem; index: number }) => (
      <FadeInOnMountView duration={400} style={{ flex: 1 }}>
        <FeaturedCarouselSlide
          slideData={item}
          currentSlide={currentSlide}
          onVideoEnd={onVideoEnd}
          slideIndex={index}
          cancelAutoSlide={setIsAutoSlideActive.setFalse}
          key={item.id}
        />
      </FadeInOnMountView>
    ),
    [currentSlide, onVideoEnd, setIsAutoSlideActive.setFalse]
  )

  return (
    <Carousel
      style={{ marginTop: CAROUSEL_MARGIN_TOP }}
      ref={carouselRef}
      loop={slides.length > 1}
      width={carouselWidth}
      height={carouselHeight}
      data={slides}
      autoPlay={false}
      scrollAnimationDuration={300}
      mode="parallax"
      modeConfig={{
        parallaxScrollingScale: 0.89,
        parallaxScrollingOffset: carouselWidth * 0.125,
        parallaxAdjacentItemScale: 0.83,
      }}
      onSnapToItem={setCurrentSlide} // Consider to use onProgressChanged instead to avoid UI change delays
      renderItem={renderItem}
      // This resolves the issue of the carousel suppressing the vertical scroll of the FlatList
      // https://github.com/dohooo/react-native-reanimated-carousel/issues/125
      panGestureHandlerProps={{
        activeOffsetX: [-10, 10],
      }}
    />
  )
})
dosubot[bot] commented 5 months ago

Hey @MetaBenji! I'm Dosu, a bot that's here to help you solve bugs, answer questions, and become a contributor. Let's get to the bottom of this issue together!

To resolve the issue with react-native-reanimated-carousel where changing the device orientation causes some items not to render when using the windowSize prop, you should ensure that the windowSize prop is correctly set, as the carousel will prioritize windowSize over itemsCount.

Additionally, a recent patch has been made to the library to re-calculate when the window size changes, which should help address rendering issues related to orientation changes:

---
'react-native-reanimated-carousel': patch
---

re-calculate when window size changed in browser.

This means that if you are experiencing rendering issues, you may need to adjust the windowSize prop to ensure it is appropriate for the number of items and the new orientation, and ensure you are using the latest version of the library that includes this patch [1][2].

To continue talking to Dosu, mention @dosu.

padvlad commented 2 months ago

I stumbled upon the same issue while using the latest beta version at this point (4.0.0-alpha.12). This seems to be indeed a bug.

@MetaBenji Found a hacky way of working around the issue by slightly changing the windowSize param when the orientation changes; not pretty, but it does the job:

import { useWindowDimensions } from 'react-native';

...

const { width, height } = useWindowDimensions();

...
...

<Carousel
    ref={ref}
    windowSize={width < height ? 3 : 4}
    width={width}
    data={data}
    ....
/>
nusoloman commented 1 month ago

same problem