React Swiper:未捕获(承诺中)TypeError:无法读取未定义的属性(读取“addClass”)

问题描述 投票:0回答:5

我正在使用反应打字稿。当我在滑动滑块组件上设置

thumbs={{ swiper: thumbsSwiper }}
时,它给我一个错误
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'addClass')
。我怎样才能解决它?如果我在 js 文件中使用以下代码,它不会给我任何错误,但一旦我在 TSX 文件上使用它,就会出现错误。

const [thumbsSwiper, setThumbsSwiper] = useState<any>(null); // Thumbs state

<div key={product._id} className='lg:w-1/2'>
        <Swiper

            loop={true}
            spaceBetween={10}
            thumbs={{ swiper: thumbsSwiper }} // PRoblem is Here
            modules={[FreeMode, Navigation, Thumbs]}
            className="mySwiper2"
        >
            {product?.images.map(({ src }: { src: string }) => {
                return <SwiperSlide style={{ height: '500px', width: '300px' }}>
                    <img src={src} alt={product?.title} />
                </SwiperSlide>

            })}
        </Swiper>
        <Swiper
            onSwiper={setThumbsSwiper}
            loop={true}
            spaceBetween={10}
            slidesPerView={4}
            freeMode={true}
            watchSlidesProgress={true}
            modules={[FreeMode, Navigation, Thumbs]}
            className="mySwiper mt-4"
        >
            {product?.images.map(({ src }: { src: string }) => {
                return <SwiperSlide style={{ height: '100px', width: '100px' }} >
                    <img src={src} alt={product?.title} />
                </SwiperSlide>

            })}
        </Swiper>
    </div>

这是我的完整代码:

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import RelatedProducts from '../RelatedProducts/RelatedProducts';
import { Swiper, SwiperSlide } from "swiper/react";
import { FreeMode, Navigation, Thumbs } from "swiper";
import Magnifier from "react-magnifier";

const SingleProduct = () => {
    const { id } = useParams();
    const [productsDetails, setProductsDetails] = useState<any>([])
    const [isLoading, setIsLoading] = useState<boolean>(false)

    useEffect(() => {
        setIsLoading(true)
        fetch(`https://guarded-ocean-73313.herokuapp.com/products`)
            .then(res => res.json())
            .then((data) => {
                console.log(data, 'data')
                const product = data.filter(detail => detail._id === id)
                setProductsDetails(product);
            }).finally(() => setIsLoading(false))

    }, [id])

    useEffect(() => {
        if (!productsDetails.length) {
            <h2>Loading</h2>
        }
    }, [productsDetails.length])


    const [thumbsSwiper, setThumbsSwiper] = useState<any>(null);
    return (
        <div>

            <section className="text-gray-700 body-font overflow-hidden bg-white">
                <div className="container px-5 py-10 mx-auto">

                    <div className="lg:w-4/5 mx-auto flex ">
                        {isLoading ? "Loading" :
                            productsDetails.map(product => {
                                return <>
    <div key={product._id} className='lg:w-1/2'>
        <Swiper

            loop={true}
            spaceBetween={10}
            thumbs={{ swiper: thumbsSwiper }}
            modules={[FreeMode, Navigation, Thumbs]}
            className="mySwiper2"
        >
            {product?.images.map(({ src }: { src: string }) => {
                return <SwiperSlide style={{ height: '500px', width: '300px' }}>
                    <img src={src} alt={product?.title} />
                </SwiperSlide>

            })}
        </Swiper>
        <Swiper
            onSwiper={setThumbsSwiper}
            loop={true}
            spaceBetween={10}
            slidesPerView={4}
            freeMode={true}
            watchSlidesProgress={true}
            modules={[FreeMode, Navigation, Thumbs]}
            className="mySwiper mt-4"
        >
            {product?.images.map(({ src }: { src: string }) => {
                return <SwiperSlide style={{ height: '100px', width: '100px' }} >
                    <img src={src} alt={product?.title} />
                </SwiperSlide>

            })}
        </Swiper>
    </div>
                                    <div className="lg:w-1/2 w-full lg:pl-10 lg:py-6 mt-6 lg:mt-0">
                                        <div>
                                            <h2 className="text-sm title-font text-gray-500 tracking-widest">Brand: <b>{product.brand}</b></h2>
                                            <h1 className="text-gray-900 text-3xl title-font font-medium mb-1">{product.title}</h1>
                                            <div className="flex mb-4">
                                                <span className="flex items-center">
                                                    <svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-4 h-4 text-red-500" viewBox="0 0 24 24">
                                                        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
                                                    </svg>
                                                    <svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-4 h-4 text-red-500" viewBox="0 0 24 24">
                                                        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
                                                    </svg>
                                                    <svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-4 h-4 text-red-500" viewBox="0 0 24 24">
                                                        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
                                                    </svg>
                                                    <svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-4 h-4 text-red-500" viewBox="0 0 24 24">
                                                        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
                                                    </svg>
                                                    <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-4 h-4 text-red-500" viewBox="0 0 24 24">
                                                        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
                                                    </svg>
                                                    <span className="text-gray-600 ml-3">4 Reviews</span>
                                                </span>
                                                <span className="flex ml-3 pl-3 py-2 border-l-2 border-gray-200">
                                                    <a className="text-gray-500">
                                                        <svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-5 h-5" viewBox="0 0 24 24">
                                                            <path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"></path>
                                                        </svg>
                                                    </a>
                                                    <a className="ml-2 text-gray-500">
                                                        <svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-5 h-5" viewBox="0 0 24 24">
                                                            <path d="M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2c9 5 20 0 20-11.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z"></path>
                                                        </svg>
                                                    </a>
                                                    <a className="ml-2 text-gray-500">
                                                        <svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-5 h-5" viewBox="0 0 24 24">
                                                            <path d="M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z"></path>
                                                        </svg>
                                                    </a>
                                                </span>
                                            </div>
                                            <p className="leading-relaxed"
                                                dangerouslySetInnerHTML={({ __html: product.product_des })}></p>

                                            <div className="flex py-4 space-x-4">

                                            </div>
                                            <div className="flex mt-6 items-center pb-5 border-b-2 border-gray-200 mb-5">
                                                {/* <div className="flex">
                                                    <span className="mr-3">Color</span>
                                                    <button className="border-2 border-gray-300 rounded-full w-6 h-6 focus:outline-none"></button>
                                                    <button className="border-2 border-gray-300 ml-1 bg-gray-700 rounded-full w-6 h-6 focus:outline-none"></button>
                                                    <button className="border-2 border-gray-300 ml-1 bg-red-500 rounded-full w-6 h-6 focus:outline-none"></button>
                                                </div> */}
                                                <div className="relative mr-4 mt-3">
                                                    <div className="text-center left-0 pt-2 right-0 absolute block text-xs uppercase text-gray-400 tracking-wide font-semibold">Qty</div>
                                                    <select className="cursor-pointer appearance-none rounded-xl border border-gray-200 pl-4 pr-8 h-14 flex items-end pb-1">
                                                        <option>1</option>
                                                        <option>2</option>
                                                        <option>3</option>
                                                        <option>4</option>
                                                        <option>5</option>
                                                    </select>
                                                </div>

                                                {product?.attributes.map(attr => {
                                                    return <div className=" mr-6 items-center">
                                                        <span className="mr-3"><b>{attr.label}</b></span><br />
                                                        <div className="relative">
                                                            <select className="rounded appearance-none border border-gray-200 py-2 focus:outline-none focus:border-indigo-500 text-base pl-3 pr-10">
                                                                {attr?.selected.map(select => {
                                                                    return <option>{select.label}</option>
                                                                })}

                                                            </select>
                                                            <span className="absolute right-0 top-0 h-full w-10 text-center text-gray-600 pointer-events-none flex items-center justify-center">
                                                                <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-4 h-4" viewBox="0 0 24 24">
                                                                    <path d="M6 9l6 6 6-6"></path>
                                                                </svg>
                                                            </span>
                                                        </div>
                                                    </div>
                                                })}


                                            </div>
                                            <span className="title-font font-sm  text-gray-900">Category: <b>{product.categories[0].label}</b></span>
                                            <div className="flex mt-4">
                                                <div className="inline-block align-bottom mr-5">
                                                    <span className="text-2xl leading-none align-baseline">$</span>
                                                    <span className="font-bold text-5xl leading-none align-baseline">{product.sale_price ? product.sale_price : product.reg_price} </span>
                                                    <span className="text-2xl leading-none align-baseline">.00</span>
                                                </div>
                                                <div className="inline-block align-bottom mr-5 mt-5 line-through">
                                                    <span className="text-2xl leading-none align-baseline">$</span>
                                                    <span className="font-bold text-2xl leading-none align-baseline">{product.sale_price ? product.reg_price : ''} </span>
                                                    <span className="text-2xl leading-none align-baseline">.00</span>
                                                </div>
                                                {/* <span className="title-font font-medium text-2xl text-gray-900">${product.price | 0}        <span className='line-through text-gray-500'>{product?.sale_price}</span>
                                                </span> */}
                                                <button className="flex ml-auto text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded items-center">Add to cart</button>
                                                <button className="rounded-full w-10 h-10 bg-gray-200 p-0 border-0 inline-flex items-center justify-center text-gray-500 ml-4">
                                                    <svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" className="w-5 h-5" viewBox="0 0 24 24">
                                                        <path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"></path>
                                                    </svg>
                                                </button>
                                            </div>
                                        </div>
                                    </div></>
                            })
                        }



                    </div>
                </div>
                <div className='bg-slate-300 mb-10 mt-10 shadow'>
                    <h2 className='text-2xl text-center py-3'>Related Products</h2>
                </div>
                <RelatedProducts />
            </section >

        </div >



    )
};

export default SingleProduct;
javascript reactjs swiper.js react-typescript react-swiper
5个回答
6
投票

如果您在模态中打开

Swiper
,请在每次关闭模态时将 null 传递给
setThumbsSwiper
。这对我有用。

const onCloseModal = () => {
 setThumbsSwiper(null)
}

https://snipboard.io/pN3cIl.jpg


1
投票

我是这样解决的。我首先验证我的图像属性上是否有任何可用图像,如果有图像,则渲染 swiperSlide 它解决了我的问题。

{
    product.images ? <Swiper

        loop={true}
        spaceBetween={10}
        thumbs={{ swiper: thumbsSwiper }}
        modules={[FreeMode, Navigation, Thumbs]}
        className="mySwiper2"
    >
        {product?.images.map(({ src }: { src: string }) => {
            return <SwiperSlide style={{ height: '500px', width: '300px' }}>
                <img src={src} alt={product?.title} />
            </SwiperSlide>

        })}
    </Swiper> : 'No img'
}

1
投票

React 不允许将 className 传递给 swiper 组件,但有两种方法可以实现此目的

  1. 反应严格来自
  2. 将Swiper Js升级到最新版本

此解决方案之一肯定适合您。


1
投票

对我来说这解决了问题

 thumbs={{swiper: thumbsSwiper && !thumbsSwiper.destroyed ? thumbsSwiper : null}}

0
投票

对我来说,我清理了 useEffect 上的拇指滑动器

useEffect(()=>{
  return ()=>{
    setThumbSwiper(null)
  }
},[])
© www.soinside.com 2019 - 2024. All rights reserved.