---
title: "EC サイト向け React カテゴリーレール"
description: "React の横型カテゴリーレール：ネイティブスクロール、端で無効になる矢印、画像の遅延読み込みと分析のためのアイテムごとの可視性。デモとソース付き。"
canonical: "https://react-horizontal-scrolling-menu.dev/ja/category-rail"
image: "https://react-horizontal-scrolling-menu.dev/og.png"
---

# React で作る、あなたのストア向けカテゴリーレール

カテゴリーレール — ストアフロントのグリッドの上にある、タップ可能な部門の行 — は EC サイトの中で最もトラフィックの多いスクロールコンテナであり、それらはカルーセルではなくメニューです：すべてのタイルはリンクで、何もスナップせず、端で半分だけ見えるタイルがスクロールへと誘います。

TTokyo

OOslo

LLima

CCairo

SSydney

QQuito

SSeoul

PPorto

DDenver

HHanoi

レールをドラッグするか矢印を使ってみてください — 行の本当の端で無効になります。

[この例を Storybook でライブ編集](https://asmyshlyaev177.github.io/react-horizontal-scrolling-menu/?path=/story/examples-simple--simple)

## なぜストアフロントではネイティブスクロールが勝つのか

ストアフロントのレールは、1 ポイントの Lighthouse スコアのために戦うページのファーストビューに存在します。カルーセルエンジンは、ブラウザがネイティブに行うことをするために数十キロバイトのジェスチャーエミュレーションを出荷します。このライブラリは min+gzip で ≈5.7 kB で、スクロールをプラットフォームに任せるため、ハイドレーションのカクつきがありません — レールは JavaScript が読み込まれる前からスクロールでき、それはクローラーが見るサーバーレンダリングされた HTML の中でも動作するということでもあります。このページ自体がサーバーレンダリングの証拠です：上のデモは JavaScript を無効にしてもスクロールします。

[比較ページ](https://react-horizontal-scrolling-menu.dev/ja/compare.md) に、Swiper、Embla、keen-slider、react-slick との全項目の比較表があります。

## 可視性トラッキングはストアフロントの機能

アイテムごとの可視性は、マーチャンダイジングに結びつけるまでは実装の細部に聞こえます：

-   **画像の遅延読み込み** — `useIsVisible` が画面内にあると報告するまでプレースホルダータイルをレンダリングします。
-   **インプレッション分析** — `getVisible()`（ホームページの [ヒーローデモ](https://react-horizontal-scrolling-menu.dev/ja.md) で実際に動いています）は、レールがレンダリングされたことだけでなく、どのカテゴリーが実際に見られたかを正確に教えてくれます。
-   **エッジ対応の矢印** — [add-items の例](https://react-horizontal-scrolling-menu.dev/ja/examples/add-items.md) のように、カテゴリーが非同期で後から読み込まれても、本当の端で無効化・非表示になります。

## あなたのデザインシステムに合わせる

タイルはあなたのコンポーネントです — 画像カード、円形、テキストピルなど — それぞれが `itemId` を持ちます。高さと幅はあなたの CSS 由来で、メニューは寸法を一切強制しません。[one-item-scroll](https://react-horizontal-scrolling-menu.dev/ja/examples/one-item-scroll.md) で商品スライダーのように 1 アイテムずつ進めたり、スクロールの [進捗インジケーター](https://react-horizontal-scrolling-menu.dev/ja/examples/progress.md) を表示したり、[RTL の例](https://react-horizontal-scrolling-menu.dev/ja/examples/rtl.md) でアラビア語やヘブライ語のストア向けに RTL 対応で出荷したりできます — レールは設定ではなく構成の産物です。

## パターン、最小構成

`itemId` を持つタイルと、可視性フックからの矢印 — レール全体は 40 行未満です。

CategoryRail.tsx

```
function CategoryRail({ categories }: { categories: Category[] }) {
  return (
    <ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
      {categories.map((category) => (
        <CategoryTile itemId={category.id} key={category.id} {...category} />
      ))}
    </ScrollMenu>
  );
}

function CategoryTile({ itemId, name, image }: CategoryTileProps) {
  // Lazy images for free: placeholders until the tile is on screen.
  const visibility = React.useContext<publicApiType>(VisibilityContext);
  const isVisible = visibility.useIsVisible(itemId, false);
  return (
    <a href={`/category/${itemId}`} className="rail-tile">
      {isVisible ? <img src={image} alt="" /> : <div className="ph" />}
      <span>{name}</span>
    </a>
  );
}

function LeftArrow() {
  const visibility = React.useContext<publicApiType>(VisibilityContext);
  const atStart = visibility.useLeftArrowVisible();
  return (
    <button disabled={atStart} onClick={() => visibility.scrollPrev()}>
      ←
    </button>
  );
}
```

## または shadcn コンポーネントとしてインストール

ベースとなる [scroll-menu](https://react-horizontal-scrolling-menu.dev/r/scroll-menu.json) レジストリアイテムがこのレールです — shadcn スタイルの矢印、ドラッグスクロール、非表示のスクロールバー — あなたの `components/ui/` にインストールされ、あなたのトークンでスタイリングされます：

shadcn

```
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/scroll-menu.json
```

## 関連する例

-   [はじめに最小のメニュー：項目、2 つの矢印、すぐ使える可視性。](https://react-horizontal-scrolling-menu.dev/ja/examples/simple.md)
-   [一度に 1 項目スクロール矢印がページではなく 1 項目ずつ進めます。](https://react-horizontal-scrolling-menu.dev/ja/examples/one-item-scroll.md)
-   [スクロール進捗インジケーターどの項目が見えているかで動く進捗バー。](https://react-horizontal-scrolling-menu.dev/ja/examples/progress.md)

[すべての例（21 件）](https://react-horizontal-scrolling-menu.dev/ja/examples.md)

---

More examples: <https://react-horizontal-scrolling-menu.dev/examples.md>
Library summary for LLMs: <https://react-horizontal-scrolling-menu.dev/llms.txt>
