import React, {
  useRef,
  useState,
  useEffect,
  useCallback,
  forwardRef,
  useImperativeHandle,
} from 'react';
import { makeStyles } from '@material-ui/core/styles';
import cx from 'clsx';

const useStyles = makeStyles(() => ({
  slider: {
    display: 'flex',
    position: 'relative',
    scrollSnapType: 'x mandatory',
    overflowX: 'scroll',
    width: '100%',
    scrollbarWidth: 'none',
    MsOverflowStyle: 'none',

    '&::-webkit-scrollbar': {
      display: 'none',
    },
  },
  slideWrapper: {
    scrollSnapAlign: 'start',
    flexShrink: 0,
    width: '100%',
  },
}));

const Slider = (
  {
    className,
    children,
    autoplay = false,
    interval = 3000,
    slideWrapperClassName,
    initIndex = 0,
    onSlideChange = () => {},
  },
  ref
) => {
  const classes = useStyles();

  const [activeSlide, setActiveSlide] = useState(initIndex);
  const [timeoutId, setTimeoutId] = useState(null);

  const sliderRef = useRef(null);

  const slides = React.Children.toArray(children);
  const slidesAmount = slides.length;

  const slideTo = useCallback(
    (index, smooth = true) => {
      const slider = sliderRef.current;

      if (slider) {
        slider.scrollTo({
          left: slider.scrollWidth * (index / slidesAmount),
          behavior: smooth ? 'smooth' : 'auto',
        });
      }
    },
    [slidesAmount]
  );

  const autoplayNext = useCallback(() => {
    if (timeoutId) {
      clearTimeout(timeoutId);
      setTimeoutId(null);
    }

    const id = setTimeout(() => {
      const nextSlide = activeSlide === slidesAmount - 1 ? 0 : activeSlide + 1;
      slideTo(nextSlide);
    }, interval);

    setTimeoutId(id);
  }, [slidesAmount, activeSlide, interval, timeoutId, slideTo]);

  useImperativeHandle(
    ref,
    () => ({
      activeIndex: activeSlide,
      slideTo,
      reset: () => {
        slideTo(initIndex);

        if (autoplay) {
          autoplayNext();
        }
      },
    }),
    [activeSlide, slideTo, initIndex, autoplay, autoplayNext]
  );

  useEffect(() => {
    const slider = sliderRef.current;

    slideTo(initIndex, false);

    const onScroll = () => {
      const slider = sliderRef.current;

      if (slider) {
        const index = Math.round(
          (slider.scrollLeft / slider.scrollWidth) * slidesAmount
        );

        setActiveSlide(index);
      }
    };

    if (slider) {
      slider.addEventListener('scroll', onScroll);
    }

    return () => {
      if (slider) {
        slider.removeEventListener('scroll', onScroll);
      }
    };

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sliderRef, slidesAmount]);

  useEffect(() => {
    if (autoplay) {
      autoplayNext();
    } else {
      clearTimeout(timeoutId);
    }

    return () => {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
    };

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoplay, activeSlide, interval]);

  useEffect(() => {
    onSlideChange(activeSlide);
  }, [activeSlide, onSlideChange]);

  return (
    <div ref={sliderRef} className={cx(classes.slider, className)}>
      {slides.map((slide, index) => (
        <div
          key={index}
          className={cx(classes.slideWrapper, slideWrapperClassName)}
        >
          {slide}
        </div>
      ))}
    </div>
  );
};

export default forwardRef(Slider);

@@ -875,17 +875,16 @@
   const 
-%5B
 timeoutI
@@ -888,42 +888,25 @@
 utId
-, setTimeoutId%5D
  = use
-State
+Ref
 (null);%0A
 %0A  c
@@ -893,33 +893,32 @@
 = useRef(null);%0A
-%0A
   const sliderRe
@@ -1389,32 +1389,40 @@
    if (timeoutId
+.current
 ) %7B%0A      clearT
@@ -1429,32 +1429,40 @@
 imeout(timeoutId
+.current
 );%0A      setTime
@@ -1454,28 +1454,25 @@
 ;%0A      
-setT
+t
 imeoutId
 (null);%0A
@@ -1463,22 +1463,31 @@
 imeoutId
-(
+.current = 
 null
-)
 ;%0A    %7D%0A
@@ -1654,20 +1654,17 @@
     
-setT
+t
 imeoutId
 (id)
@@ -1663,12 +1663,21 @@
 utId
-(
+.current = 
 id
-)
 ;%0A  
@@ -2747,24 +2747,32 @@
 ut(timeoutId
+.current
 );%0A    %7D%0A%0A  
@@ -2807,16 +2807,24 @@
 imeoutId
+.current
 ) %7B%0A    
@@ -2849,16 +2849,24 @@
 imeoutId
+.current
 );%0A     

store slider's timeoutId with ref instead of state