React ガイド

@reelkit/react でスライダーを作る方法を説明します。

タッチ優先
慣性とスナップのあるスワイプ
キーボード操作
矢印キーと Escape
ホイールスクロール
任意、デバウンス付き
仮想化
10,000 件以上、DOM には 3 つ
インジケーター
Instagram 風のドットのスクロール
プログラムからの操作
ref で next()、prev()、goTo()
ループモード
終わりのない循環ナビゲーション
方向を選べる
縦でも横でも
再レンダリングなし
シグナルによる状態の更新

Reel コンポーネント

Reel コンポーネントはメインのコンテナーです。スライダーの状態を管理し、タッチジェスチャー、キーボード操作、アニメーションを処理します。

tsx

サイズの自動計測

size プロップは任意です。省略すると、Reel は ResizeObserver でコンテナーを自動計測し、CSS で決まるレイアウトに合わせます。コンテナーのサイズは親要素で決める必要があります(flex、grid、または CSS での明示的な寸法など)。

tsx

itemBuilder パターン

itemBuilder プロップは、インデックスを受け取って各スライドの内容を返す関数です。このパターンによって仮想化が可能になり、表示中のアイテムだけが描画されます。

tsx

組み込みの操作方法:

  • タッチ/スワイプ: ドラッグで移動し、慣性とスナップが効きます
  • キーボード: 矢印キーと Escape
  • マウスホイール: enableWheel プロップで有効にします
  • プログラムから: apiRefnext()prev()goTo() を呼びます
tsx

URL の状態

useOverlayUrlState はオーバーレイ用の URL 状態コントローラーを作り、そのまま返します。それを *UrlOverlaycontroller プロップに渡します。開閉状態は URL が持つので、結び付けられたオーバーレイは自分で開き、開く操作は通常リンクになります。存在しないパラメーターへの最初の書き込みは履歴エントリーを 1 つ積み、以降の書き込みはそれを置き換えるので、ページを送っても戻るボタンが埋もれることはありません。コントローラーは手元に残しておき、valueposition を読んだり、プログラムから操作したりするのに使います。set(position) で開き、set(null) で閉じます。set は、オーバーレイがスライドの切り替え時に内部で使っているのと同じ低レベルの書き込みです。

tsx

オプションのオブジェクトは paramcodeclocator(3 つとも必須)と、任意の adapter を受け取ります。paramadapter は最初の描画で読まれ、その後は固定です(変えるには再マウントします)。一方 codeclocator は毎回読まれるので、リストが伸びたり並べ替えられたりしたあとの検索では、現在のリストが見えます。codeclocator は同じ Id を共有する対なので、一緒に扱います。単純な ?photo=3 のギャラリーなら ...urlIndexKey(() => images.length) を展開すれば、両方が一度に返されます。urlIndexKey はパラメーターをスライドのインデックスに対応させ、getter が返す現在の件数で範囲を制限するので、古いまたは範囲外の ?photo=99 は拒否され、指されていないスライドを開く代わりに URL から自動で取り除かれます。数値ではなく getter を渡してください。そうすればページングされたフィードが伸びても範囲が正しく保たれます。内部では createIndexLocator(locator の側)を包み、indexCodec と組み合わせています。ページングされたフィードや識別子で指すギャラリーは、代わりに独自の codeclocator の対を用意します。すべてのオプションの表は React API リファレンス にあります。

ReelIndicator

スライダー内の現在位置を示す、Instagram 風の進捗インジケーターを表示する任意のコンポーネントです。Reel の中に置くと、コンテキストを通じて親の countactive の値に自動で接続するので、状態を手でつなぐ必要はありません。

tsx

ライブデモ:基本のスライダー

タッチ/スワイプ
慣性付き
キーボード
矢印キーと Escape
インジケーター
Instagram 風
ナビゲーション
apiRef から
BasicSlider.tsx

試してみてください。ボタンをクリックするとスライドを移動できます。

ポイント

  • size プロップ

    任意の [幅, 高さ] のタプルです。省略すると CSS でサイズが決まります

  • itemBuilder

    インデックスを受け取り、スライドの内容を返します

  • apiRef

    ナビゲーションのためにコントローラーのメソッドへアクセスします

  • afterChange

    UI を更新するために現在のインデックスを追跡します

ライブデモ:無限リスト

reelkit は常に DOM に 3 枚のスライド(現在・前・次)だけを描画します。これにより、10,000 件を超えるリストでもなめらかにスクロールできます。

DOM に 3 つ
表示中のスライドだけを描画
10,000 件以上
どの規模でもカクつきません
一定のメモリ
件数に関係なく DOM ノードは同じ 3 つ
goTo(n)
任意のインデックスへすぐ移動
InfiniteList.tsx

10,000 件のうち DOM にあるのは 3 つだけ。ボタンを使うか、数字を入力して移動してください。

ライブデモ:伸びていくリスト

TikTok や Instagram のように、必要に応じてアイテムを読み込む無限フィードを再現しています。20 件から始まり、終わり近くまでスクロールすると新しいバッチが自動で届きます。

件数が変わる
スクロールに合わせて読み込み
バッチ読み込み
1 バッチ 20 件
仮想化
それでも DOM には 3 つだけ
自動インジケーター
コンテンツに合わせてドットが増えます
GrowableList.tsx
1 / 20 (growing)

最後までスクロールすると、新しいアイテムが自動で読み込まれます。バッチが届くたびにカウンターとインジケーターが増えます。

パフォーマンスのヒント

  • データの配列をメモ化する

    アイテムの配列を useMemo で包んでください。描画のたびに配列の参照が新しくなると、count の更新と表示範囲の再計算が起きます。

  • itemBuilder を軽く保つ

    表示範囲が変わるたびに(通常は 3 枚分)実行されます。中で重い計算や副作用を行わないでください。

  • 端に近づいたらデータを読み込む

    afterChange でユーザーが終わりに近づいたことを検知し、スライドが尽きる前に次のバッチを取得します(上の伸びていくリストのデモを参照)。

  • スクロールするページではホイールを無効にする

    スクロールするレイアウトの中にスライダーを埋め込むときは、ページのスクロールを奪わないよう enableWheel={false} を指定してください。

次のステップ