YIZHUANG / react-multi-carousel

A lightweight production-ready Carousel that rocks supports multiple items and server-side rendering with no dependency. Bundle size 2kb.
MIT License
1.25k stars 286 forks source link

Dynamic responsive object not updating carousel until screen size change #360

Open derochedesign opened 1 year ago

derochedesign commented 1 year ago

I'm using my slider container width to set the items and slidesToSlide values. My component receives the width (say, 600), then I divide that by the card width (say, 200). In this case, both values would be 3. As shown in this video, the console is demonstrating that the code works. The responsive object is updated with the proper number of items on rerender. However, the carousel itself won't update until I change the screen size again.

I would expect that the carousel would update when the component rerenders and the responsive object has changed. I understand that this isn't the expected way to use this package, but it seems to work perfectly other than for this issue.

Video here: https://files.catbox.moe/h90wqc.mov

Relevant code:

const [sliderWidth, setSliderWidth] = useState(0);

useEffect(() => {
  setSliderWidth(containerRef.current.offsetWidth);
}, [screenSize]);

const carouselResponsive = {
  bp: {
    breakpoint: {max: 10000, min: 0},
    items: Math.round(sliderWidth/AVG_TILE_WIDTH),
    slidesToSlide: Math.round(sliderWidth/AVG_TILE_WIDTH)
  } 
}

return (
  <Carousel responsive={carouselResponsive} arrows={false} customButtonGroup={<ButtonGroup />}>
    {children}
  </Carousel>
)

(I can get a reproducable example up later if necessary)

derochedesign commented 1 year ago

For the time being I've solved this by forcing the component to re-create itself when the screen size has changed, but it's not a good solution and I'd like something better than this long term.

return (
  <>
    {!adjustingScreenSize &&
      <Carousel
        containerClass="tile-carousel-slider"
        responsive={carouselResponsive}
        arrows={false}
        customButtonGroup={<ButtonGroup />}
      >
        {children}
      </Carousel>
    }
  </>
);
MalabarFront commented 9 months ago

You can fudge this by manually triggering the browser's resize event, which is still not great, but a little cleaner.

window.dispatchEvent(new Event('resize'));