为何无法在Swiper中直接使用自定义组件<Foo />?
问题
在Swiper中直接嵌套<SwiperSlide>可以正常运行:
<Swiper> <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> </Swiper>
但将<SwiperSlide>封装成自定义组件后,使用<Foo />的方式无法正常工作:
const Foo = () => <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-3.jpg" /> </SwiperSlide> ; <Swiper> <Foo /> </Swiper>
改用函数调用{Foo()}的方式可以运行,但希望能正常使用<Foo />写法,完整代码如下:
import React, { useRef, useState } from "react"; // Import Swiper React components import { Swiper, SwiperSlide } from "swiper/react"; // Import Swiper styles import "swiper/css"; import "swiper/css/pagination"; import "swiper/css/navigation"; import "swiper/css/navigation"; import "swiper/css/effect-fade"; import "./styles.css"; // import required modules import { EffectFade, Autoplay, Pagination, Navigation } from "swiper"; export default function App() { return ( <> <Swiper effect="fade" loop={true} navigation={true} spaceBetween={30} centeredSlides={true} autoplay={{ delay: 5000, disableOnInteraction: false, pauseOnMouseEnter: true }} pagination={{ clickable: true }} modules={[EffectFade, Autoplay, Pagination, Navigation]} className="mySwiper" > <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-1.jpg" /> </SwiperSlide> <Foo /> </Swiper> </> ); } const Foo = () => ( <SwiperSlide> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> );
解决方案
原因
Swiper的React组件内部是通过直接检测子元素是否为<SwiperSlide>组件来识别轮播项的,当用自定义组件<Foo />包裹时,Swiper拿到的子元素是Foo组件而非直接的SwiperSlide,因此无法识别它作为轮播项。而调用{Foo()}本质是直接执行函数返回SwiperSlide元素,相当于直接传入了SwiperSlide,所以能正常工作。
修复方法
有两种直接的解决方式:
- 让自定义组件以
SwiperSlide为根节点并透传props
修改Foo组件,确保其渲染的根元素就是SwiperSlide,同时透传所有可能的props,保证Swiper能正常识别:
const Foo = (props) => ( <SwiperSlide {...props}> <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> );
这样<Foo />写法就能被Swiper正常识别为轮播项。
- 通过children实现更灵活的结构(可选)
如果需要自定义组件包裹更多内容,可以让组件接收children,但仍保持SwiperSlide作为根节点:
const Foo = ({ children }) => ( <SwiperSlide> {children} <img src="https://swiperjs.com/demos/images/nature-2.jpg" /> </SwiperSlide> );
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

