React Flickity Slider初始渲染flickityRef未定义致点击跳转失效
React Flickity Slider 点击跳转异常问题
问题详情
- 已解决初始渲染时
flickityRef返回undefined导致onEngagement回调在组件重渲染前无法工作的问题。 - 当前新问题:当滑块内渲染带筛选功能的组件时,初始渲染阶段点击滑块元素无法跳转至对应位置;但点击筛选触发组件重渲染、或开发环境热重载后,该功能恢复正常;渲染其他组件时无此问题。
组件代码
import React, { useRef, useEffect, useCallback } from "react"; import { isBrowser } from "@cryos/helpers/browser.helper"; import Flickity from "flickity"; export interface ICarouselProps { content: JSX.Element[] | undefined; previewNext?: boolean; startIndex?: number; fullscreen?: boolean; cellAlign?: "left" | "right" | "center"; onCarouselChangeCallback?: (index: number) => void; getFlickityRef?: (ref: Flickity) => void; /** * Triggered when certain events happen for tracking purposes. */ onEngagement?: () => void; dontChangeSlideOnClick?: boolean; } export const Carousel = React.memo<ICarouselProps>((props) => { const { content, previewNext, onCarouselChangeCallback, startIndex, fullscreen, onEngagement, dontChangeSlideOnClick, getFlickityRef, } = props; const FlickityComponent = isBrowser ? require("react-flickity-component") : "div"; const flickityRef = useRef<Flickity>(); let cellAlignment = previewNext ? "left" : "center"; cellAlignment = props.cellAlign ? props.cellAlign : cellAlignment; const handleOnEngagement = useCallback(() => { onEngagement?.(); }, [onEngagement]); const setFlickityRef = useCallback( (ref: Flickity) => { flickityRef.current?.off("change", handleOnEngagement); flickityRef.current = ref; if (getFlickityRef) { getFlickityRef(ref); } flickityRef.current?.on("change", handleOnEngagement); }, [handleOnEngagement, getFlickityRef], ); useEffect(() => { const flickity = flickityRef.current; const onChange = (index?: number) => { if (typeof index !== "undefined" && onCarouselChangeCallback) { onCarouselChangeCallback(index); } }; const onStaticClick = (_event?: Event, _pointer?: Element | Touch, _cellElement?: Element, cellIndex?: number) => { if (typeof cellIndex !== "undefined" && !dontChangeSlideOnClick && flickity) { flickity.select(cellIndex); } }; if (flickity) { flickity.on("change", onChange); flickity.on("staticClick", onStaticClick); } return () => { if (flickity) { flickity.off("change", onChange); flickity.off("staticClick", onStaticClick); } }; }, [content, onCarouselChangeCallback, dontChangeSlideOnClick]); return ( <> {content && content.length > 1 ? ( <div className={`c-carousel ${previewNext ? "c-carousel--preview" : ""} ${ fullscreen ? "c-carousel--fullscreen" : "" }`} > <FlickityComponent flickityRef={setFlickityRef} className="c-carousel__flickity" options={{ dragThreshold: 10, imagesLoaded: true, arrowShape: "M 20,50 L 70,100 L 75,95 L 30,50 L 75,5 L 70,0 Z", cellAlign: cellAlignment, initialIndex: startIndex || 0, setGallerySize: true, }} > {content} </FlickityComponent> </div> ) : ( <>{content && content[0]}</> )} </> ); }); Carousel.displayName = "Carousel";
内容的提问来源于stack exchange,提问作者ComCool
相关产品推荐
相关产品推荐

