我想在使用React钩子挂载某个组件时初始化Swiper实例。调整大小后,我想根据视口宽度销毁或更新Swiper实例。
我正在使用useEffect
钩子初始化插件,在其中我调用存储为const
的函数。
const MyComponent = () => {
const [swiper, setSwiper] = useSate(null);
const element = useRef(null);
const initSwiper = useCallback(() => {
// swiper is always null here so I can't destroy the instance
if (MediaQuery.is('large up') && swiper !== null) {
return setSwiper(swiper.destroy());
}
if (MediaQuery.is('small up')) {
const currentSwiper = new Swiper(element.current, swiperSettings);
currentSwiper.init();
return setSwiper(currentSwiper);
}
}, [swiper, swiperSettings]);
useEffect(() => {
initSwiper();
window.addEventListener('resize', initSwiper);
return () => {
window.removeEventListener('resize', initSwiper);
}
}, []);
return (
<div ref={element}>...</div>
}
我想知道初始化后如何访问Swiper实例。我应该使用ref
吗?我不太确定最好的方法是什么。
答案 0 :(得分:2)
您实际上不需要此处的状态。由于useEffect()
回调是一个闭包,并且您没有在闭包外使用swiper
,因此请创建一个变量(let swiper
)并分配Swiper
的当前实例到变量。您还应该在闭包内部声明initSwiper
,由于useEffect()
块仅在init上运行,因此您不需要(实际上也不能)用useEffect()
来包装它。>
注意:swiperSettings
不是来自道具或状态,因此useEffect()
块并不依赖于它们。如果您需要通过props
进行更改,请通过参考传递它们。
const MyComponent = () => {
const element = useRef(null);
useEffect(() => {
let swiper = null;
const initSwiper = () => {
if (MediaQuery.is('large up') && swiper !== null) {
swiper = swiper.destroy();
} else if (MediaQuery.is('small up')) {
// swiper.destroy(); // should probably start by destroying the old swiper
swiper = new Swiper(element.current, swiperSettings);
swiper.init();
}
};
window.addEventListener('resize', initSwiper);
return () => {
window.removeEventListener('resize', initSwiper);
}
}, []);
return (
<div ref={element}>...</div>
);
};
并用作自定义钩子(如suggest by @PatrickRoberts):
const useSwiper = () => {
const element = useRef(null);
useEffect(() => {
let swiper = null;
const initSwiper = () => {
if (MediaQuery.is('large up') && swiper !== null) {
swiper = swiper.destroy();
} else if (MediaQuery.is('small up')) {
// swiper.destroy(); // should probably start by destroying the old swiper
swiper = new Swiper(element.current, swiperSettings);
swiper.init();
}
};
window.addEventListener('resize', initSwiper);
return () => {
window.removeEventListener('resize', initSwiper);
}
}, []);
return element;
};
const MyComponent = () => (
<div ref={useSwiper()} />
);