react-alice-carousel、react-image-gallery、react-responsive-carousel 和 react-slick 都是 React 生态中用于实现滑动内容展示的主流库。它们解决了图片画廊、产品轮播、内容滑块等常见 UI 需求,但在底层实现、服务端渲染(SSR)支持、内容灵活性以及维护状态上存在显著差异。react-slick 是最老牌的选择但依赖 jQuery 时代的 slick 样式;react-image-gallery 专注于图片展示功能;react-responsive-carousel 提供了平衡的通用性;而 react-alice-carousel 则以轻量和高 SSR 兼容性著称。
在 React 项目中选择轮播图组件不仅仅是选一个能滑动的 UI 库,更是关于 SSR 兼容性、依赖管理和长期维护的决策。react-alice-carousel、react-image-gallery、react-responsive-carousel 和 react-slick 代表了四种不同的设计思路。本文将从工程化角度深入对比它们的核心差异。
依赖的复杂性直接影响构建配置。react-slick 需要额外引入 CSS 依赖,而其他库通常自包含或只需引入单一 CSS 文件。
react-alice-carousel
npm install react-alice-carousel
/* 需引入样式 */
import 'react-alice-carousel/lib/alice-carousel.css';
react-image-gallery
npm install react-image-gallery
/* 需引入样式 */
import "react-image-gallery/styles/css/image-gallery.css";
react-responsive-carousel
npm install react-responsive-carousel
/* 需引入样式 */
import "react-responsive-carousel/lib/styles/carousel.min.css";
react-slick
npm install react-slick slick-carousel
/* 必须引入两个 CSS 文件,依赖外部包 */
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
所有库都提供了顶层组件,但 Props 结构差异明显。react-image-gallery 需要特定的数据格式,而其他库接受 React 节点。
react-alice-carousel
import AliceCarousel from 'react-alice-carousel';
const items = [
<div className="item">1</div>,
<div className="item">2</div>,
<div className="item">3</div>,
];
const Gallery = () => <AliceCarousel items={items} />;
react-image-gallery
import ImageGallery from "react-image-gallery";
const images = [
{ original: "img1.jpg", thumbnail: "thumb1.jpg" },
{ original: "img2.jpg", thumbnail: "thumb2.jpg" },
];
const Gallery = () => <ImageGallery items={images} />;
react-responsive-carousel
import { Carousel } from 'react-responsive-carousel';
const Gallery = () => (
<Carousel>
<div><img src="img1.jpg" /></div>
<div><img src="img2.jpg" /></div>
<div><img src="img3.jpg" /></div>
</Carousel>
);
react-slick
import Slider from "react-slick";
const settings = { dots: true, infinite: true, slidesToShow: 1 };
const Gallery = () => (
<Slider {...settings}>
<div><img src="img1.jpg" /></div>
<div><img src="img2.jpg" /></div>
<div><img src="img3.jpg" /></div>
</Slider>
);
这是选型的关键分水岭。react-image-gallery 专为图片设计,其他库则支持任意 React 节点。
react-alice-carousel
支持任意 React 节点,适合混合内容(文本 + 图片 + 组件)。
const items = [
<Card title="Product A" price={100} />, // 自定义组件
<img src="banner.jpg" alt="Banner" />, // 图片
<div className="text-slide">Sale Info</div> // 纯文本
];
react-image-gallery
仅限图片对象结构,不支持直接渲染自定义组件作为 slide。
// 必须遵循 { original, thumbnail } 结构
const items = [{ original: "url", thumbnail: "url" }];
// 无法直接传入 <MyComponent />
react-responsive-carousel
支持任意子组件,灵活性高,类似原生 React 组合模式。
<Carousel>
<MyCustomSlideComponent data={data} />
<img src="image.jpg" />
</Carousel>
react-slick
支持任意子组件,但需注意样式隔离,防止 slick 默认样式干扰。
<Slider>
<div className="custom-card">Content</div>
<img src="image.jpg" />
</Slider>
在 Next.js 或 Remix 中,SSR 兼容性至关重要。react-slick 常因 DOM 操作导致水合失败,而 react-alice-carousel 对此优化较好。
react-alice-carousel
对 SSR 友好,通常无需额外配置即可避免水合警告。
// 直接在服务端组件中渲染,通常无警告
<AliceCarousel items={items} />
react-image-gallery
支持 SSR,但建议确保图片尺寸在服务端已知,避免布局偏移。
// 确保图片加载前布局稳定
<ImageGallery items={images} />
react-responsive-carousel
支持 SSR,但在某些严格模式下可能需要动态导入。
// 若遇到窗口对象未定义错误,使用 next/dynamic
const Carousel = dynamic(() => import('...').then(mod => mod.Carousel), { ssr: false });
react-slick
已知存在 SSR 问题,常需禁用 SSR 或添加特定配置。
// 推荐在客户端渲染以避免水合不匹配
const Slider = dynamic(() => import("react-slick"), { ssr: false });
不同库处理断点的方式不同。react-slick 和 react-alice-carousel 提供详细的断点配置,而其他库更多依赖 CSS 或简单 Props。
react-alice-carousel
使用 responsive 对象定义断点,逻辑清晰。
const responsive = {
0: { items: 1 },
720: { items: 3 },
1024: { items: 5 },
};
<AliceCarousel items={items} responsive={responsive} />
react-image-gallery
主要通过 CSS 控制缩略图显示,幻灯片本身通常全屏或固定比例。
// 通过 CSS 媒体查询控制缩略图栏
<ImageGallery items={images} showThumbnails={true} />
react-responsive-carousel
使用 responsive 数组或对象,支持细粒度控制。
<Carousel
responsive={{
0: { items: 1 },
640: { items: 2 },
1024: { items: 3 }
}}
>
{/* items */}
</Carousel>
react-slick
使用 responsive 数组,配置项丰富但较繁琐。
const settings = {
responsive: [
{ breakpoint: 1024, settings: { slidesToShow: 3 } },
{ breakpoint: 600, settings: { slidesToShow: 1 } }
]
};
<Slider {...settings}>{/* items */}</Slider>
了解库的长期维护情况对于架构决策至关重要。
react-alice-carousel
活跃维护,专注于 React 现代特性,无沉重历史包袱。
react-image-gallery
维护稳定,专注于垂直领域(图片画廊),功能迭代较慢但可靠。
react-responsive-carousel
社区活跃,更新频繁,是通用轮播场景的安全选择。
react-slick
底层依赖 slick-carousel 已多年未更新,存在潜在安全风险和兼容性隐患,新项目不建议作为首选。
| 特性 | react-alice-carousel | react-image-gallery | react-responsive-carousel | react-slick |
|---|---|---|---|---|
| 内容类型 | 任意 React 节点 | 仅图片对象 | 任意 React 节点 | 任意 React 节点 |
| SSR 支持 | ✅ 优秀 | ✅ 良好 | ✅ 良好 | ⚠️ 需动态导入 |
| 依赖复杂度 | 低 | 中 | 低 | 高 (需 slick-carousel) |
| 内置灯箱 | ❌ 需自行实现 | ✅ 内置 | ❌ 需自行实现 | ❌ 需自行实现 |
| 维护状态 | 🟢 活跃 | 🟢 稳定 | 🟢 活跃 | 🟡 维护缓慢 |
| 配置难度 | 中 | 低 | 中 | 高 |
react-alice-carousel 是现代 React 架构(尤其是 Next.js/Remix)中的首选通用方案,因为它平衡了灵活性和 SSR 兼容性。
react-image-gallery 是特定场景的最优解,如果你只需要展示图片且需要开箱即用的灯箱功能,不要重复造轮子。
react-responsive-carousel 是一个稳健的备选方案,适合需要高度定制化 UI 但不想处理底层滑动逻辑的团队。
react-slick 建议仅用于维护旧项目。在新架构中,其依赖模型和 SSR 问题会带来不必要的技术债务。
最终选择应基于内容类型(是否仅为图片)和渲染环境(是否强依赖 SSR)。避免为了熟悉度而选择过时的技术栈。
如果你的项目需要完美的服务端渲染(SSR)支持,或者需要展示非图片的复杂 React 组件(如表单、卡片),选择 react-alice-carousel。它轻量且配置灵活,适合现代 Next.js 或 Remix 架构,避免了传统轮播库的水合错误问题。
如果你的需求严格局限于图片展示,且需要内置的缩略图、全屏灯箱(Lightbox)和滑动切换功能,选择 react-image-gallery。它省去了自行实现图片预览逻辑的工作,适合摄影作品集或电商商品图展示。
如果你需要一个通用性强、文档完善且社区活跃的轮播组件,选择 react-responsive-carousel。它在功能丰富度和配置复杂度之间取得了平衡,支持多种滑动模式,适合大多数标准的内容轮播场景。
如果你正在维护旧项目,或者团队非常熟悉 Slick Carousel 的配置方式,可以选择 react-slick。但在新项目中需谨慎,因为其底层依赖已停止维护,且在教学渲染环境中容易出现样式闪烁或水合不匹配问题。
React Alice Carousel is a React component for building content galleries, content rotators and any React carousels.


npm i react-alice-carousel
# CSS
@import "react-alice-carousel/lib/alice-carousel.css";
# SCSS
@import "react-alice-carousel/lib/scss/alice-carousel.scss";
import React from 'react';
import AliceCarousel from 'react-alice-carousel';
import 'react-alice-carousel/lib/alice-carousel.css';
const handleDragStart = (e) => e.preventDefault();
const items = [
<img src="https://raw.githubusercontent.com/maxmarinich/react-alice-carousel/HEAD/path-to-img" onDragStart={handleDragStart} role="presentation" />,
<img src="https://raw.githubusercontent.com/maxmarinich/react-alice-carousel/HEAD/path-to-img" onDragStart={handleDragStart} role="presentation" />,
<img src="https://raw.githubusercontent.com/maxmarinich/react-alice-carousel/HEAD/path-to-img" onDragStart={handleDragStart} role="presentation" />,
];
const Gallery = () => <AliceCarousel mouseTracking items={items} />;
activeIndex : Number, default 0 - Set carousel at the specified position.
animationDuration: Number, default 400 - Set duration of animation.
animationEasingFunction: String or Function, default ease - Property sets how an animation progresses through the duration of each cycle.
animationType: String(slide, fadeout), default slide - Set type of animation.
autoHeight: Boolean, default false - Set auto height mode.
autoWidth: Boolean, default false - Set auto width mode.
autoPlay: Boolean, default false - Set autoplay mode.
autoPlayControls: Boolean, default false - Show/hide play/pause buttons.
autoPlayDirection: String(ltr, rtl), default ltr - Set autoplay direction value.
autoPlayInterval: Number, default 400 - Set autoplay interval value.
autoPlayStrategy: String(default, action, all, none) - Set a strategy for autoplay mode
default - pause automatic playback on the hoveraction - stop automatic playback if user action was detectedall - merge default && action strategiesnone - ignore any user actions when the autoPlay property was specifiedcontrolsStrategy: String (default, responsive, alternate or combined string "default,alternate") - Set a strategy for gallery controls.
default - use controls as isalternate - show each dot for each slideresponsive - navigation will be hidden if the number of gallery elements is equal to the number of items in the slide.disableButtonsControls: Boolean, default false - Disable buttons controls.
disableDotsControls: Boolean, default false - Disable dots controls.
disableSlideInfo: Boolean, default true - Disable information about current slide.
infinite: Boolean, default false - Set infinite mode.
innerWidth: Number, default 0 - Set a static value for a breakpoint(key) of the "responsive" property. For example, if you can't use 'window.innerWidth' during SSR.
items: Array, default undefined - Set gallery items, preferable to use this property instead of children.
keyboardNavigation: Boolean, default false - Enable keyboard navigation
ArrowLeft - go to the prev slideArrowRight - go to the next slideSpace - run/stop autoplay mode if autoPlay property is equal truemouseTracking: Boolean, default false - Enable mouse drag animation. Consider the problem with links, see the example of using the <Link/> component below.
paddingLeft: Number, default 0 - Set the gallery offset from the left.
paddingRight: Number, default 0 - Set the gallery offset from the right.
renderKey: Number, default undefined - Auxiliary property, allows call the render method without changing the state inside the gallery instance.
responsive: Object, default undefined - The key is the breakpoint (default is the result of: () => window.innerWidth or innerWidth property if the last presented).
items - set number of items in the slide. Default: 1
itemsFit: one of (contain | fill | undefined) - defines, how item should fill the container according slide's width. Default: fill.
If contain is specified, the gallery will use the value from the items property to determine the width of the element for each slide and fill in the empty space as needed.
{
0: {
items: 1,
},
1024: {
items: 3,
itemsFit: 'contain',
}
}
syncStateOnPropsUpdate: Boolean, default true - Sync some props (like activeIndex) with carousel state while new props passed. This allows you to avoid resetting the carousel position while updating the props (e.g.: children or items).
swipeDelta: Number, default 20 - Set minimum distance to the start of the swiping (px).
swipeExtraPadding: Number, default 200 - Set maximum distance from initial place before swipe action will be stopped (px).
ssrSilentMode: Boolean, default true - Disable classnames modifiers for server side rendering.
touchTracking: Boolean, default true - Enable touch move animation.
touchMoveDefaultEvents: Boolean, default true - Enable touch move default events on swiping. If false was specified, this prevents vertical scrolling of the parent elements during the swipe.
onInitialized(e: EventObject): Function - Fired as callback after the gallery was created.
onResizeEvent(e: Event): Function, default shouldProcessResizeEvent method - Fired during the "resize" event to determine whether to call the event handler. Default method checks is the root element width has changed.
onResized(e: EventObject): Function - Fired as callback after the gallery was resized.
onUpdated(e: EventObject): Function - Fired as callback after updating the gallery props.
onSlideChange(e: EventObject): Function - Fired before the event object changes.
onSlideChanged(e: EventObject): Function - Fired after the event object was changed.
renderSlideInfo(e: SlideInfo): Rendering function - create a custom component.
renderDotsItem(e: DotsItem): Rendering function - create a custom component.
renderPrevButton({ isDisabled }): Rendering function - create a custom component.
renderNextButton({ isDisabled }): Rendering function - create a custom component.
renderPlayPauseButton({ isPlaying }): Rendering function - create a custom component.
slidePrev(e: Event) => void : Go to the prev slide.slideNext(e: Event) => void : Go to the next slide.slideTo(activeIndex?: number) => void : Go to the specified slide.<Link /> : allows properly handle click and drag events when mouseTracking enabled, extends base HTMLAnchorElementimport React from 'react';
import AliceCarousel, { Link } from 'react-alice-carousel';
import 'react-alice-carousel/lib/alice-carousel.css';
const Gallery = () => {
return (
<AliceCarousel mouseTracking>
<Link href="#">
<img src="https://raw.githubusercontent.com/maxmarinich/react-alice-carousel/HEAD/path-to-image" />
</Link>
</AliceCarousel>
);
};
type EventObject = {
item: number;
slide: number;
itemsInSlide: number;
isPrevSlideDisabled: boolean;
isNextSlideDisabled: boolean;
type: EventType;
};
type SlideInfo = {
item: number;
itemsCount: number;
};
type DotsItem = {
isActive: boolean;
activeIndex: number;
};
enum EventType {
ACTION = 'action', // used if a general user action (button click or swipe)
INIT = 'init', // used if the initial event was triggered
RESIZE = 'resize', // used if the gallery size was changed
UPDATE = 'update', // used if the gallery was updated with props
}
.alice-carousel
.alice-carousel__stage
.alice-carousel__stage-item
.alice-carousel__prev-btn
.alice-carousel__prev-btn-item
.alice-carousel__next-btn
.alice-carousel__next-btn-item
.alice-carousel__play-btn
.alice-carousel__play-btn-item
.alice-carousel__dots
.alice-carousel__dots-item
.alice-carousel__slide-info
.alice-carousel__slide-info-item;
.alice-carousel.__ssr
.alice-carousel__stage-item.__active
.alice-carousel__stage-item.__cloned
.alice-carousel__stage-item.__target
.alice-carousel__next-btn-item.__inactive
.alice-carousel__prev-btn-item.__inactive
.alice-carousel__play-btn-item.__pause
.alice-carousel__dots-item.__active
.alice-carousel__dots-item.__custom
.alice-carousel__slide-info-item.__separator;
git clone https://github.com/maxmarinich/react-alice-carousel
cd react-alice-carousel
npm ci
npm start
npm test
MIT