embla (which is set to useEmblaCarousel()) before I do the resizing, the object is _not_ null or undefined.scrollNext/scrollPrev methods to not work.const OverflowContainer = styled.div`
overflow: hidden;
height: 100%;
min-width: 80%;
`;
const FlexContainer = styled.div`
display: flex;
height: 100%;
width: 80%;
`;
const Slide = styled.div`
position: relative;
flex: 0 0 15%;
height: 80%;
`;
const PreviousButton = styled.button`
cursor: pointer;
background-color: green;
width: 30px;
height: 30px;
`;
const NextButton = styled.button`
cursor: pointer;
background-color: blue;
width: 30px;
height: 30px;
`;
interface Props {
slides: JSX.Element[];
}
const ExampleCarousel = ({mergedVideos}: Props) => {
const [carouselRef, embla] = useEmblaCarousel();
const scrollPrev = useCallback(() => {
embla && embla.scrollPrev(); // embla evaluates properly here - failure happens in scrollPrev()?
}, [embla]);
const scrollNext = useCallback(() => {
embla && embla.scrollNext(); // embla evaluates properly here - failure happens in scrollNext()?
}, [embla]);
const slideVideos = slides.map((m) => <Slide key={m.key}>{m}</Slide>);
return (
<>
<OverflowContainer ref={carouselRef}>
<FlexContainer>{slideVideos}</FlexContainer>
</OverflowContainer>
<PreviousButton onClick={scrollPrev} />
<NextButton onClick={scrollNext} />
</>
);
};
export default ExampleCarousel;
Thank you! Let me know if there's anything else I can provide... If this weren't a client project, I would have gifs and other accompanying pieces for you. :( Apart from this strange issue, I've loved using Embla so far!
Hi EJ (@ej-mitchell),
Thank you for the clear issue description. I can't be 100% sure because I don't have access to your full setup, but I don't think this is a bug. I think this is happening because one of the following reasons:
display: none or similar when it's initialized the first time. This makes it impossible for Embla to pick up any slide or container dimensions.Embla Carousel has no internal mechanism for picking up any changes in slides. This has to be done manually by telling Embla to reinitialize. The reason why it works when you resize the window is because Embla automatically calls embla.reInit() on window resize, which will do a hard reset and pick up any slides inside its container.
If this is happening because of reason 1, try the following solution:
useEffect(() => {
if (embla && embla.slideNodes().length !== slides.length) {
embla.reInit() // If the slides prop length changes, pick it up
}
}, [
embla,
slides /* Add slides as a dependency to trigger this when the prop changes */
])
If it's happening because of reason 2, pass null instead of the carouselRef until you've removed the display: none style. This will work because Embla will reinitialize when the ref changes. Something along these lines:
const [carouselReady, setCarouselReady] = useState(false)
return (
...
<OverflowContainer ref={carouselReady ? carouselRef : null}>
<FlexContainer>{slideVideos}</FlexContainer>
</OverflowContainer>
...
)
Let me know if it helps.
Best,
David
Thank you so much, @davidcetinkaya ! This was a lovely and concise answer. I will give that a go. 馃樃 I will close the issue, too since this is not a bug.
@ej-mitchell let me know how it goes when you've tried my suggestions 馃憤.
It worked 馃樆 thank you! (I had a hunch that it was scenario 1)
Thanks for confirming @ej-mitchell 馃憤. Enjoy!
Most helpful comment
Thanks for confirming @ej-mitchell 馃憤. Enjoy!