2023年7月28日に更新 - 仮想スライドの実装追加
リアクトでスワイパーウェブコンポーネントを使用する方法の詳細をご紹介します。
パラメーター
リアクトはカスタム要素(ウェブコンポーネント)をネイティブではまだサポートしていないため、このコードは
<swiper-container
slides-per-view={3}
breakpoints={{
768: {
slidesPerView: 4,
},
}}
>
...
</swiper-container>
実際には以下のようにレンダリングされます。
<swiper-container slides-per-view="3" breakpoints="[object Object]">
...
</swiper-container>
これは期待したものと異なります。
このため、プロパティとしてパラメーターを渡す、カスタム初期化を使用する必要がスワイパー要素をリアクトで使用することになります
import { useEffect, useRef } from 'react';
import { register } from 'swiper/element/bundle';
export default function App() {
const swiperRef = useRef(null);
useEffect(() => {
// Register Swiper web component
register();
// Object with parameters
const params = {
slidesPerView: 3,
breakpoints: {
768: {
slidesPerView: 4,
},
},
};
// Assign it to swiper element
Object.assign(swiperRef.current, params);
// initialize swiper
swiperRef.current.initialize();
}, []);
return (
<swiper-container init="false" ref={swiperRef}>
...
</swiper-container>
);
}
イベント
イベントも同様に、リアクトのon[Event]
構文を使用して割り当てられず、.addEventListener
メソッドを使用するか、パラメーターでon
に渡すことで追加する必要があります
import { useEffect, useRef } from 'react';
import { register } from 'swiper/element/bundle';
export default function App() {
const swiperRef = useRef(null);
useEffect(() => {
// Register Swiper web component
register();
// Add event listener
swiperRef.current.addEventListener('swiperslidechange', (e) => {
console.log(e.detail);
});
// Object with parameters
const params = {
// or pass it in on
on: {
slideChange(s) {
console.log(s);
},
},
};
// Assign it to swiper element
Object.assign(swiperRef.current, params);
// initialize swiper
swiperRef.current.initialize();
}, []);
return (
<swiper-container init="false" ref={swiperRef}>
...
</swiper-container>
);
}
カスタムラッパコンポーネント
プロジェクトにスワイパーがたくさんある場合は、スワイパー要素をラップするシンプルなリアクトコンポーネントを作成できます
import { useEffect, useRef } from 'react';
import { register } from 'swiper/element/bundle';
export function Swiper(props) {
const swiperRef = useRef(null);
const {
children,
...rest
} = props;
useEffect(() => {
// Register Swiper web component
register();
// pass component props to parameters
const params = {
...rest
};
// Assign it to swiper element
Object.assign(swiperRef.current, params);
// initialize swiper
swiperRef.current.initialize();
}, []);
return (
<swiper-container init="false" ref={swiperRef}>
{children}
</swiper-container>
);
}
export function SwiperSlide(props) {
const {
children,
...rest
} = props;
return (
<swiper-slide {...rest}>
{children}
</swiper-slide>
);
}
これで、アプリ全体で次のように使用できます。
import { Swiper, SwiperSlide } from 'path/to/my-swiper.jsx';
export default function App() {
return (
<Swiper
slidesPerView={3}
breakpoints={{ 768: { slidesPerView: 4 } }}
on={{
slideChange: () => console.log('slide changed'),
progress: (s, progress) => console.log(`progress is ${progress}`),
}}
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
</Swiper>
);
}
仮想スライド
仮想スライドを使用する場合、さらに掘り下げて仮想スライドをリアクトでも実装できます。次の方法でSwiper
コンポーネントを少し変更する必要があります。
import React, { useEffect, useState, useRef } from 'react';
import { register } from 'swiper/element/bundle';
export function Swiper(props) {
const swiperRef = useRef(null);
const {
children,
virtual, // specify virtual prop
...rest
} = props;
// store virtual data
const [virtualData, setVirtualData] = useState({
from: 0,
to: 0,
offset: 0,
slides: [],
});
useEffect(() => {
// Register Swiper web component
register();
// pass component props to parameters
const params = {
...rest
};
// if we have virtual prop passed add virtual prameters
if (virtual) {
params.virtual = {
enabled: true,
// pass component children (slides) in `slides` array
slides: children,
// set virtual data on renderExternal
renderExternal(vd) {
setVirtualData(vd);
},
};
}
// Assign it to swiper element
Object.assign(swiperRef.current, params);
// initialize swiper
swiperRef.current.initialize();
}, []);
// calc slides to render
const slides = virtual
? virtualData.slides.map((slide, index) =>
// clone slide
React.cloneElement(slide, {
// add key
key: virtualData.from + index,
// set slides offset
style: {
[props.direction === "vertical" ? "top" : "left"]:
virtualData.offset,
},
// add and swiper slide index to data attribute
["data-swiper-slide-index"]: virtualData.from + index,
})
)
: children; // return children if virtual is disabled
return (
<swiper-container init="false" ref={swiperRef}>
{slides}
</swiper-container>
);
}
// SwiperSlide component stays the same
export function SwiperSlide(props) {
const {
children,
...rest
} = props;
return (
<swiper-slide {...rest}>
{children}
</swiper-slide>
);
}
これで、リアクトで仮想スライドを含むスワイパーを簡単に作成できます。
import { Swiper, SwiperSlide } from 'path/to/my-swiper.jsx';
export default function App() {
return (
<Swiper virtual navigation>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
...
<SwiperSlide>Slide 1000</SwiperSlide>
</Swiper>
);
}
追伸
いつも通り、スワイパーがお気に入りの場合は、寄付またはプレッジでプロジェクトをサポートしてください
- Patreon:https://www.patreon.com/swiperjs
- Open Collective:https://opencollective.com/swiper
プレミアムプロジェクトの確認
サポートは私たちにとって非常に重要です!