---
title: "Riel de categorías en React para e-commerce"
description: "Un riel de categorías horizontal en React: scroll nativo, flechas que se desactivan en los bordes, visibilidad por elemento para imágenes diferidas y analítica. Demo y código."
canonical: "https://react-horizontal-scrolling-menu.dev/es/category-rail"
image: "https://react-horizontal-scrolling-menu.dev/og.png"
---

# Un riel de categorías para tu tienda, en React

Los rieles de categorías —la fila pulsable de departamentos sobre la cuadrícula de una tienda— son los contenedores de scroll con más tráfico en e-commerce, y son menús, no carruseles: cada mosaico es un enlace, nada encaja a la fuerza, y que medio mosaico asome en el borde es justo lo que invita a desplazarse.

TTokyo

OOslo

LLima

CCairo

SSydney

QQuito

SSeoul

PPorto

DDenver

HHanoi

Arrastra el riel o usa las flechas: se desactivan en los extremos reales de la fila.

[Edita este ejemplo en vivo en Storybook](https://asmyshlyaev177.github.io/react-horizontal-scrolling-menu/?path=/story/examples-simple--simple)

## Por qué el scroll nativo gana en una tienda

Los rieles de tienda viven sobre el pliegue, en páginas donde peleas por cada punto de Lighthouse. Un motor de carrusel distribuye decenas de kilobytes de emulación de gestos para hacer lo que el navegador ya hace de forma nativa; esta librería pesa ≈5.7 kB min+gzip y deja el scroll a la plataforma, así que no hay parpadeo de hidratación: el riel se desplaza antes de que se cargue tu JavaScript, lo que también significa que funciona en el HTML renderizado en el servidor que ven tus rastreadores. Esta misma página es la prueba, renderizada en el servidor: la demo de arriba se desplaza con JavaScript desactivado.

La [página de comparación](https://react-horizontal-scrolling-menu.dev/es/compare.md) tiene la tabla completa frente a Swiper, Embla, keen-slider y react-slick.

## El seguimiento de visibilidad es una función de tienda

La visibilidad por elemento suena como un detalle de implementación hasta que la aplicas al merchandising:

-   **Imágenes diferidas** — renderiza un mosaico marcador de posición hasta que `useIsVisible` indique que está en pantalla.
-   **Analítica de impresiones** — `getVisible()` (en vivo en la [demo del hero](https://react-horizontal-scrolling-menu.dev/es.md) de la página de inicio) te dice exactamente qué categorías se vieron, no solo que el riel se renderizó.
-   **Flechas conscientes de los bordes** — se desactivan u ocultan en los extremos reales, incluso después de que las categorías se carguen de forma asíncrona, como en el [ejemplo de añadir elementos](https://react-horizontal-scrolling-menu.dev/es/examples/add-items.md).

## Ajústalo a tu sistema de diseño

Los mosaicos son tus componentes —tarjetas con imagen, círculos, píldoras de texto— cada uno con un `itemId`. La altura y el ancho vienen de tu CSS; el menú no impone dimensiones. Avanza de un elemento en uno como un slider de producto con [one-item-scroll](https://react-horizontal-scrolling-menu.dev/es/examples/one-item-scroll.md), muestra un [indicador de progreso](https://react-horizontal-scrolling-menu.dev/es/examples/progress.md) del scroll, o distribúyelo en RTL para tiendas en árabe y hebreo con el [ejemplo RTL](https://react-horizontal-scrolling-menu.dev/es/examples/rtl.md): el riel es composición, no configuración.

## El patrón, en su forma mínima

Mosaicos con un `itemId`, flechas a partir de los hooks de visibilidad: el riel completo tiene menos de cuarenta líneas.

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>
  );
}
```

## O instálalo como componente shadcn

El elemento base del registro [scroll-menu](https://react-horizontal-scrolling-menu.dev/r/scroll-menu.json) es este riel —flechas con estilo shadcn, arrastre para desplazar, barra de scroll oculta— instalado en tu `components/ui/` y con estilos según tus tokens:

shadcn

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

## Ejemplos relacionados

-   [Primeros pasosEl menú mínimo: elementos, dos flechas, visibilidad lista para usar.](https://react-horizontal-scrolling-menu.dev/es/examples/simple.md)
-   [Desplazarse de un elemento en unoLas flechas avanzan un solo elemento en lugar de una página completa.](https://react-horizontal-scrolling-menu.dev/es/examples/one-item-scroll.md)
-   [Indicador de progreso de desplazamientoUna barra de progreso impulsada por qué elementos son visibles.](https://react-horizontal-scrolling-menu.dev/es/examples/progress.md)

[Todos los ejemplos (21)](https://react-horizontal-scrolling-menu.dev/es/examples.md)

---

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