Next.js14中使用Swiper Thumbs模块报错:无法转undefined/null为对象
解决Next.js 14 + Swiper v11.0.5缩略图组件的"Cannot convert undefined or null to object"错误
问题根源
这个错误是因为主Swiper初始化时,缩略图Swiper还未完成实例化,导致thumbs属性传入了无效值;或者组件重渲染时,实例状态出现不一致,触发了Swiper内部的对象转换错误。
可行解决方案
方案1:延迟主Swiper渲染,确保缩略图实例存在
通过条件渲染,等缩略图Swiper实例生成后再渲染主Swiper,避免初始时传入无效值:
import React, { useState } from "react"; import { Swiper, SwiperSlide } from "swiper/react"; import "swiper/css"; import "swiper/css/free-mode"; import "swiper/css/navigation"; import "swiper/css/thumbs"; import "./styles.css"; import { Navigation, Thumbs, A11y, Scrollbar } from "swiper/modules"; export default function SwiperComp() { const [thumbsSwiper, setThumbsSwiper] = useState(null); return ( <> <ModalWrapper> {/* 只有缩略图实例存在时才渲染主Swiper */} {thumbsSwiper && ( <Swiper thumbs={{ swiper: thumbsSwiper }} modules={[Navigation, Thumbs, A11y, Scrollbar]} > <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-3.jpg" /> </SwiperSlide> </Swiper> )} <Swiper onSwiper={setThumbsSwiper} spaceBetween={10} slidesPerView={10} watchSlidesProgress={true} modules={[Navigation, Thumbs, A11y]} > <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-3.jpg" /> </SwiperSlide> </Swiper> </ModalWrapper> </> ); }
方案2:用useEffect同步实例状态,手动更新配置
监听缩略图实例的变化,动态更新主Swiper的thumbs配置,同时处理组件重渲染时的实例同步:
import React, { useState, useEffect, useRef } from "react"; import { Swiper, SwiperSlide } from "swiper/react"; import "swiper/css"; import "swiper/css/free-mode"; import "swiper/css/navigation"; import "swiper/css/thumbs"; import "./styles.css"; import { Navigation, Thumbs, A11y, Scrollbar } from "swiper/modules"; export default function SwiperComp() { const [thumbsSwiper, setThumbsSwiper] = useState(null); const [mainThumbsConfig, setMainThumbsConfig] = useState(null); const swiperRef = useRef(null); useEffect(() => { if (thumbsSwiper && !thumbsSwiper.destroyed) { setMainThumbsConfig({ swiper: thumbsSwiper }); // 主Swiper已实例化时,手动更新缩略图配置 if (swiperRef.current?.swiper) { swiperRef.current.swiper.thumbs.swiper = thumbsSwiper; } } }, [thumbsSwiper]); return ( <> <ModalWrapper> <Swiper ref={swiperRef} thumbs={mainThumbsConfig} modules={[Navigation, Thumbs, A11y, Scrollbar]} > <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-3.jpg" /> </SwiperSlide> </Swiper> <Swiper onSwiper={setThumbsSwiper} spaceBetween={10} slidesPerView={10} watchSlidesProgress={true} modules={[Navigation, Thumbs, A11y]} > <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-3.jpg" /> </SwiperSlide> </Swiper> </ModalWrapper> </> ); }
方案3:优化缩略图Swiper的初始化时机
给缩略图Swiper添加preloadImages={false}配置,避免图片加载阻塞实例初始化,同时确保它在主Swiper之前渲染:
// 修改缩略图Swiper的配置 <Swiper onSwiper={setThumbsSwiper} spaceBetween={10} slidesPerView={10} watchSlidesProgress={true} modules={[Navigation, Thumbs, A11y]} preloadImages={false} // 添加这行 > <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-3.jpg" /> </SwiperSlide> </Swiper>
内容的提问来源于stack exchange,提问作者Hithesh kumar
相关产品推荐
相关产品推荐

