maxmarinich/react-alice-carousel

Re-render problem

ChrisCoder9000 opened this issue · 3 comments

A setState called inside the onSlideChanged causes a sort of rerender of the slider that resets to the first index of the slide

<AliceCarousel
          mouseTracking
          // autoPlay
          items={elements}
          onSlideChanged={(e) => setCurSlide(e.slide)}
          disableButtonsControls={true}
          activeIndex={1}
          infinite={true}
          {...Object.assign({}, isDesktop ? extraCarouselProps : null)}
          renderDotsItem={(e) => {
            return (
              <div
                className={`dot-item ${e.isActive ? "dot-item-active" : null}`}
              >
                &nbsp;
              </div>
            );
          }}
        />

with onSlideChange the re-render doesn't happen. Am I missing someting or this is a bug that can be fixed?

Hi, @ChrisCoder9000! Please provide the full code sample.

@maxmarinich sure!

const TheGame = () => {
  const { isDesktop } = useResponsive(MOBILE_BREAKPOINT_MEDIUM);
  const [curSlide, setCurSlide] = useState(1);
  const [elements, setElements] = useState([]);

useEffect(() => {
    setElements(
      optionButtons.map((option, i) => {
        return (
          <div
            className={`option-wrapper ${
              curSlide === i ? "option-wrapper-active" : null
            }`}
            key={option.id}
          >
            <img
              src={option.image}
              data-aos="fade-up"
              data-aos-duration="1000"
              data-aos-delay={`50 * ${i * 2}`}
              data-aos-easing="ease-in-out"
              data-aos-once="true"
              data-aos-anchor-placement="top-bottom"
              className={`option-image option-image-${option.id}`}
              alt={option.title}
            />
            <div className="option-text-wrapper">
              <h2 className="option-title">{option.title}</h2>
              <p className="option-description">{option.description}</p>
            </div>
          </div>
        );
      })
    );
  }, [curSlide]);

  const extraCarouselProps = {
    paddingLeft: window.innerWidth * 0.25,
    paddingRight: window.innerWidth * 0.25,
  };

  return (
    <div className="section__the-game">
      <div className="options-list">
        <AliceCarousel
          mouseTracking
          // autoPlay
          items={elements}
          onSlideChanged={(e) => setCurSlide(e.slide)}
          disableButtonsControls={true}
          activeIndex={1}
          infinite={true}
          {...Object.assign({}, isDesktop ? extraCarouselProps : null)}
          renderDotsItem={(e) => {
            return (
              <div
                className={`dot-item ${e.isActive ? "dot-item-active" : null}`}
              >
                &nbsp;
              </div>
            );
          }}
        />
      </div>
    </div>
  );
};

export default TheGame;```

The issue related with react flow. It try rerenders each time when new props or setState. In your case it happens because setElements calls and creates newelements each time. The gallery gets new items and since you pass activeIndex === 1, navigates to this index . To resolve the issue pass activeIndex as curSlide.