英文:
Destroy and reinit Swiper instance when an attribute is updated
问题
在第一次运行时,要检查Swiper实例是否已初始化,以避免调用swiperRef.current.destroy(true, true)
,可以添加一个条件来检查swiperRef.current
是否存在且已初始化。您可以像这样修改代码:
useEffect(() => {
if (swiperRef.current && swiperRef.current.initialized) { // 添加对initialized属性的检查
console.log(swiperRef.current);
// Destroy Swiper instance when updating.
swiperRef.current.destroy(true, true);
}
// Init Swiper instance.
if (!swiperRef.current) {
swiperRef.current = new Swiper(containerRef.current, {
// Swiper配置
});
}
}, [images, fx, auto]);
通过检查swiperRef.current
是否存在且initialized
属性为true,您可以确保只有在Swiper实例已经初始化的情况下才会执行销毁操作,从而避免在第一次运行时出现错误。
英文:
I'm using the following JS code in a Gutenberg block that displays a Swiper slider:
const containerRef = useRef(null);
const swiperRef = useRef(null);
const {
attributes: { images, fx, auto },
setAttributes,
} = props;
useEffect(() => {
if (swiperRef.current) {
console.log(swiperRef.current);
// Destroy Swiper instance when updating.
swiperRef.current.destroy(true, true);
}
// Init Swiper instance.
swiperRef.current = new Swiper(containerRef.current, {
modules: [Autoplay, Navigation, EffectFade],
loop: true,
effect: fx,
fadeEffect: {
crossFade: true
},
centeredSlides: false,
autoHeight: false,
observer: true,
autoplay: auto ? {
delay: 3000,
disableOnInteraction: false,
pauseOnMouseEnter: true,
} : false,
navigation: {
nextEl: '.slider-navigation .slider-next',
prevEl: '.slider-navigation .slider-prev',
}
});
}, [images, fx, auto]);
As you can see, every time one of the attributes in the dependencies array changes, the useEffect hook is run. Inside it I check for the existence of a Swiper instance before destroying it, but for some reason in the first run (no Swiper slider is present) the swiperRef.current
conditional is true and the swiperRef.current.destroy(true, true)
call throws an error:
Uncaught TypeError: r is null
R http://example.com/wp-content/plugins/my-slider/build/blocks/slider/index.js?ver=20f7ca98c8222f0d1ea3:1
detachEvents http://example.com/wp-content/plugins/my-slider/build/blocks/slider/index.js?ver=20f7ca98c8222f0d1ea3:1
destroy http://example.com/wp-content/plugins/my-slider/build/blocks/slider/index.js?ver=20f7ca98c8222f0d1ea3:1
edit http://example.com/wp-content/plugins/my-slider/build/blocks/slider/index.js?ver=20f7ca98c8222f0d1ea3:1
commitHookEffectListMount http://example.com/wp-includes/js/dist/vendor/react-dom.js?ver=18.2.0:23160
commitPassiveMountOnFiber http://example.com/wp-includes/js/dist/vendor/react-dom.js?ver=18.2.0:24936
commitPassiveMountEffects_complete http://example.com/wp-includes/js/dist/vendor/react-dom.js?ver=18.2.0:24901
The console.log(swiperRef.current)
returns this:
{
"__swiper__": true,
"support": {
"smoothScroll": true,
"touch": false
},
"device": {
"ios": false,
"android": false
},
"browser": {
"isSafari": false,
"needPerspectiveFix": false,
"isWebView": false
},
"eventsListeners": {
"init": [
null,
null,
null,
null
],
"destroy": [
null,
null,
null,
null
],
"beforeTransitionStart": [
null
],
"sliderFirstMove": [
null
],
"touchEnd": [
null
],
"slideChange": [
null
],
"toEdge": [
null
],
"fromEdge": [
null
],
"lock": [
null
],
"unlock": [
null
],
"enable": [
null
],
"disable": [
null
],
"click": [
null
],
"beforeInit": [
null
],
"setTranslate": [
null
],
"setTransition": [
null
],
"transitionEnd": [
null
],
"virtualUpdate": [
null
]
},
"eventsAnyListeners": [],
"modules": [
null,
null,
null,
null,
null
],
"autoplay": {
"running": false,
"paused": false,
"timeLeft": 0
},
"navigation": {
"nextEl": null,
"prevEl": null
},
"params": {
"init": true,
"direction": "horizontal",
"oneWayMovement": false,
"touchEventsTarget": "wrapper",
"initialSlide": 0,
"speed": 300,
"cssMode": false,
"updateOnWindowResize": true,
"resizeObserver": true,
"nested": false,
"createElements": false,
"enabled": true,
"focusableElements": "input, select, option, textarea, button, video, label",
"width": null,
"height": null,
"preventInteractionOnTransition": false,
"userAgent": null,
"url": null,
"edgeSwipeDetection": false,
"edgeSwipeThreshold": 20,
"autoHeight": false,
"setWrapperSize": false,
"virtualTranslate": false,
"effect": "fade",
"breakpointsBase": "window",
"spaceBetween": 0,
"slidesPerView": 1,
"slidesPerGroup": 1,
"slidesPerGroupSkip": 0,
"slidesPerGroupAuto": false,
"centeredSlides": false,
"centeredSlidesBounds": false,
"slidesOffsetBefore": 0,
"slidesOffsetAfter": 0,
"normalizeSlideIndex": true,
"centerInsufficientSlides": false,
"watchOverflow": true,
"roundLengths": false,
"touchRatio": 1,
"touchAngle": 45,
"simulateTouch": true,
"shortSwipes": true,
"longSwipes": true,
"longSwipesRatio": 0.5,
"longSwipesMs": 300,
"followFinger": true,
"allowTouchMove": true,
"threshold": 5,
"touchMoveStopPropagation": false,
"touchStartPreventDefault": true,
"touchStartForcePreventDefault": false,
"touchReleaseOnEdges": false,
"uniqueNavElements": true,
"resistance": true,
"resistanceRatio": 0.85,
"watchSlidesProgress": false,
"grabCursor": false,
"preventClicks": true,
"preventClicksPropagation": true,
"slideToClickedSlide": false,
"loop": true,
"loopedSlides": null,
"loopPreventsSliding": true,
"rewind": false,
"allowSlidePrev": true,
"allowSlideNext": true,
"swipeHandler": null,
"noSwiping": true,
"noSwipingClass": "swiper-no-swiping",
"noSwipingSelector": null,
"passiveListeners": true,
"maxBackfaceHiddenSlides": 10,
"containerModifierClass": "swiper-",
"slideClass": "swiper-slide",
"slideActiveClass": "swiper-slide-active",
"slideVisibleClass": "swiper-slide-visible",
"slideNextClass": "swiper-slide-next",
"slidePrevClass": "swiper-slide-prev",
"wrapperClass": "swiper-wrapper",
"lazyPreloaderClass": "swiper-lazy-preloader",
"lazyPreloadPrevNext": 0,
"runCallbacksOnInit": true,
"_emitClasses": false,
"observer": true,
"observeParents": false,
"observeSlideChildren": false,
"autoplay": {
"enabled": false,
"delay": 3000,
"waitForTransition": true,
"disableOnInteraction": true,
"stopOnLastSlide": false,
"reverseDirection": false,
"pauseOnMouseEnter": false
},
"navigation": {
"nextEl": ".slider-navigation .slider-next",
"prevEl": ".slider-navigation .slider-prev",
"hideOnClick": false,
"disabledClass": "swiper-button-disabled",
"hiddenClass": "swiper-button-hidden",
"lockClass": "swiper-button-lock",
"navigationDisabledClass": "swiper-navigation-disabled"
},
"fadeEffect": {
"crossFade": true
},
"modules": [
null,
null,
null
]
},
"originalParams": {
"init": true,
"direction": "horizontal",
"oneWayMovement": false,
"touchEventsTarget": "wrapper",
"initialSlide": 0,
"speed": 300,
"cssMode": false,
"updateOnWindowResize": true,
"resizeObserver": true,
"nested": false,
"createElements": false,
"enabled": true,
"focusableElements": "input, select, option, textarea, button, video, label",
"width": null,
"height": null,
"preventInteractionOnTransition": false,
"userAgent": null,
"url": null,
"edgeSwipeDetection": false,
"edgeSwipeThreshold": 20,
"autoHeight": false,
"setWrapperSize": false,
"virtualTranslate": false,
"effect": "fade",
"breakpointsBase": "window",
"spaceBetween": 0,
"slidesPerView": 1,
"slidesPerGroup": 1,
"slidesPerGroupSkip": 0,
"slidesPerGroupAuto": false,
"centeredSlides": false,
"centeredSlidesBounds": false,
"slidesOffsetBefore": 0,
"slidesOffsetAfter": 0,
"normalizeSlideIndex": true,
"centerInsufficientSlides": false,
"watchOverflow": true,
"roundLengths": false,
"touchRatio": 1,
"touchAngle": 45,
"simulateTouch": true,
"shortSwipes": true,
"longSwipes": true,
"longSwipesRatio": 0.5,
"longSwipesMs": 300,
"followFinger": true,
"allowTouchMove": true,
"threshold": 5,
"touchMoveStopPropagation": false,
"touchStartPreventDefault": true,
"touchStartForcePreventDefault": false,
"touchReleaseOnEdges": false,
"uniqueNavElements": true,
"resistance": true,
"resistanceRatio": 0.85,
"watchSlidesProgress": false,
"grabCursor": false,
"preventClicks": true,
"preventClicksPropagation": true,
"slideToClickedSlide": false,
"loop": true,
"loopedSlides": null,
"loopPreventsSliding": true,
"rewind": false,
"allowSlidePrev": true,
"allowSlideNext": true,
"swipeHandler": null,
"noSwiping": true,
"noSwipingClass": "swiper-no-swiping",
"noSwipingSelector": null,
"passiveListeners": true,
"maxBackfaceHiddenSlides": 10,
"containerModifierClass": "swiper-",
"slideClass": "swiper-slide",
"slideActiveClass": "swiper-slide-active",
"slideVisibleClass": "swiper-slide-visible",
"slideNextClass": "swiper-slide-next",
"slidePrevClass": "swiper-slide-prev",
"wrapperClass": "swiper-wrapper",
"lazyPreloaderClass": "swiper-lazy-preloader",
"lazyPreloadPrevNext": 0,
"runCallbacksOnInit": true,
"_emitClasses": false,
"observer": true,
"observeParents": false,
"observeSlideChildren": false,
"autoplay": {
"enabled": false,
"delay": 3000,
"waitForTransition": true,
"disableOnInteraction": true,
"stopOnLastSlide": false,
"reverseDirection": false,
"pauseOnMouseEnter": false
},
"navigation": {
"nextEl": ".slider-navigation .slider-next",
"prevEl": ".slider-navigation .slider-prev",
"hideOnClick": false,
"disabledClass": "swiper-button-disabled",
"hiddenClass": "swiper-button-hidden",
"lockClass": "swiper-button-lock",
"navigationDisabledClass": "swiper-navigation-disabled"
},
"fadeEffect": {
"crossFade": true
},
"modules": [
null,
null,
null
]
},
"passedParams": {
"modules": [
null,
null,
null
],
"loop": true,
"effect": "fade",
"fadeEffect": {
"crossFade": true
},
"centeredSlides": false,
"autoHeight": false,
"observer": true,
"autoplay": {
"enabled": false
},
"navigation": {
"nextEl": ".slider-navigation .slider-next",
"prevEl": ".slider-navigation .slider-prev"
}
},
"enabled": true,
"el": null,
"classNames": [],
"slides": [],
"slidesGrid": [],
"snapGrid": [],
"slidesSizesGrid": [],
"activeIndex": 0,
"realIndex": 0,
"isBeginning": true,
"isEnd": false,
"translate": 0,
"previousTranslate": 0,
"progress": 0,
"velocity": 0,
"animating": false,
"allowSlideNext": true,
"allowSlidePrev": true,
"touchEventsData": {
"focusableElements": "input, select, option, textarea, button, video, label",
"lastClickTime": 0,
"velocities": [],
"evCache": []
},
"allowClick": true,
"allowTouchMove": true,
"touches": {
"startX": 0,
"startY": 0,
"currentX": 0,
"currentY": 0,
"diff": 0
},
"imagesToLoad": [],
"imagesLoaded": 0,
"initialized": false
}
Apparently, a Swiper instance is present but it's not initialized in the first run.
My question is, how can I check for this so the swiperRef.current.destroy(true, true)
is not called in the first run?
Thanks in advance
答案1
得分: 1
The Swiper实例对象似乎具有一个 initialized
属性,该属性指示Swiper实例是否已初始化。
您可以使用此属性在销毁之前检查Swiper实例是否已初始化。以下是您可以如何修改您的 useEffect
钩子的方式:
useEffect(() => {
if (swiperRef.current && swiperRef.current.initialized) {
// 在更新时销毁Swiper实例。
swiperRef.current.destroy(true, true);
}
// 初始化Swiper实例。
swiperRef.current = new Swiper(containerRef.current, {
modules: [Autoplay, Navigation, EffectFade],
loop: true,
effect: fx,
fadeEffect: {
crossFade: true
},
centeredSlides: false,
autoHeight: false,
observer: true,
autoplay: auto ? {
delay: 3000,
disableOnInteraction: false,
pauseOnMouseEnter: true,
} : false,
navigation: {
nextEl: '.slider-navigation .slider-next',
prevEl: '.slider-navigation .slider-prev',
}
});
}, [images, fx, auto]);
这样,只有在Swiper实例存在且已初始化时才会调用 swiperRef.current.destroy(true, true)
。
英文:
The Swiper instance object seems to have an initialized
property which indicates if the Swiper instance is initialized or not.
You can use this property to check if the Swiper instance is initialized before destroying it. Here's how you can modify your useEffect
hook -->
useEffect(() => {
if (swiperRef.current && swiperRef.current.initialized) {
// Destroy Swiper instance when updating.
swiperRef.current.destroy(true, true);
}
// Init Swiper instance.
swiperRef.current = new Swiper(containerRef.current, {
modules: [Autoplay, Navigation, EffectFade],
loop: true,
effect: fx,
fadeEffect: {
crossFade: true
},
centeredSlides: false,
autoHeight: false,
observer: true,
autoplay: auto ? {
delay: 3000,
disableOnInteraction: false,
pauseOnMouseEnter: true,
} : false,
navigation: {
nextEl: '.slider-navigation .slider-next',
prevEl: '.slider-navigation .slider-prev',
}
});
}, [images, fx, auto]);
This way, swiperRef.current.destroy(true, true)
will only be called if the Swiper instance exists and it's initialized.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论