我正在尝试在我的React项目中构建一个轮播组件 - 实际上,我试图利用一个用纯JS编写的现有轮播组件,使用Refs在React中使其工作,而不是直接修改DOM。当我尝试通过将序列中的第一张幻灯片标记为当前幻灯片(具有className current-slide)来初始化轮播时,我遇到了问题。我将此操作放在了一个useEffect钩子中,其中{topMovies}是依赖项。{topMovies}是一个通过prop传递给轮播组件的对象数组,因此当topMovies发生变化(即加载)时,useEffect应该运行。这个操作是有效的 - 加载后,轮播中的第一张幻灯片被赋予了classname 'current-slide'。
然而,第二段代码(nextSlide和moveToSlide)是选择下一张幻灯片的函数的开始。将track Ref(即所有幻灯片的容器)传递给函数,以便可以选择具有className 'current-slide'的子元素,并删除其className。这也是有效的 - 但是在短暂的延迟(约1秒)后,className 'current-slide'重新出现。
const Carouselv2 = ({topMovies}) =>; { //参考文献 const trackRef = useRef(); const nextBtnRef = useRef(); const prevBtnRef = useRef(); const navDotsRef = useRef(); //在道具加载时初始化轮播 const [isLoading, setIsLoading] = useState(true); useEffect(() => { if (topMovies && setIsLoading) { const Slides = Array.from(trackRef.current.children); Slides[0].classList.add('当前幻灯片'); //将第一张幻灯片标记为可见 const SlideWidth = Slides[0].getBoundingClientRect().width; const setSlidePosition = (幻灯片, 索引) => { Slide.style.left = SlideWidth * 索引 + 'px'; } 幻灯片.forEach(setSlidePosition); //将幻灯片并排排列 setIsLoading(假); } }, [热门电影]); //按钮功能 const moveToSlide = (currentSlide, targetSlide) =>; { //trackRef.current.style.transform = 'translateX(-' + targetSlide.style.left + ')'; currentSlide.classList.remove('当前幻灯片'); //targetSlide.classList.add('当前幻灯片'); } const updateDots = () =>; { } constresponsiveBtns = () =>; { } const prevSlide = (e) =>; { } const nextSlide = (e) =>; { const currentSlide = trackRef.current.querySelector('.current-slide'); const nextSlide = trackRef.current.children.nextElementSibling; moveToSlide(当前幻灯片, 下一个幻灯片); } 返回 (<按钮 className="carousel_button carousel_button--left" ref={prevBtnRef}>); }; ;; {topMovies && topMovies.map((电影) => (
- >
))}{电影.标题}
{topMovies && Array.apply(0, Array(topMovies.length)).map(() => { return })}
我最初的想法是由于某种原因,更改className导致useEffect触发,因此我添加了带有isLoading条件的if语句。但这并没有起作用,所以我不认为bug来自于useEffect钩子。
对此感到非常困惑,但这是我第一次使用Refs,所以完全有可能我错过了一些非常明显的东西。非常感谢您的帮助!
您正在混合使用React创建的DOM和使用纯Javascript操作的DOM。您不能这样做,这只会破坏DOM / VDOM关系。
如果您想避免将整个组件移动以按照React的方式工作,那么只需在空元素上使用Ref,好处是您可以获得组件挂载和卸载的好处。
然后,您几乎可以复制粘贴Javascript代码,只需将其全部放在
useEffect
中即可。例如:
下面我创建了两个按钮,一个完全由React控制,另一个由JS控制,当您点击它时,它只会切换
pink-button
类。 我还放置了一个复选框来翻转按钮的顺序以引起重新渲染,以展示JS版本的状态没有被破坏,请确保在这样做时使用key
属性让React知道它是相同的组件。这里的主要观点是展示React现在将不再干预这个按钮,它现在完全由您负责。希望这能帮助您了解如何将React与纯JS混合使用。