rc-slider、react-input-slider、react-slider はいずれも React アプリケーションで数値入力を視覚的に操作するためのスライダーコンポーネントを提供します。これらのライブラリは共通してドラッグによる値調整やキーボードナビゲーションをサポートしていますが、内部アーキテクチャ、カスタマイズ性、機能範囲、およびメンテナンス状況に大きな違いがあります。特に、rc-slider は Ant Design の公式依存パッケージとしても広く使われており、高度な機能と拡張性を備えています。一方、react-input-slider はシンプルなユースケース向けに設計されていますが、公式ドキュメントや最近の更新が確認できず、新規プロジェクトでの使用には注意が必要です。react-slider はバランスの取れたAPI設計とアクセシビリティ対応により、中規模プロジェクトに適しています。
Reactアプリで数値入力UIを実装する際、スライダーコンポーネントはよく使われるパターンです。しかし「スライダー」と一言で言っても、ライブラリごとに設計思想や実装の質が大きく異なります。本稿では、rc-slider、react-input-slider、react-slider の3つを、実際の開発現場で直面する技術的課題を中心に比較します。
まず重要な前提として、react-input-slider は 公式npmページおよびGitHubリポジトリにおいて、近年の更新が確認できず、非推奨(deprecated)と見なすべき状態 です。npmには明示的なdeprecation警告はありませんが、最後のリリースは2018年以前であり、TypeScript定義や現代的なReactライフサイクルへの対応が不十分です。新規プロジェクトでこのパッケージを採用することは、将来的なセキュリティリスクや互換性問題を招く可能性があるため、強く推奨されません。
以下では、現実的に選択肢となる rc-slider と react-slider を中心に比較します。
rc-slider: 豊富なpropsで細かい制御が可能rc-slider はAnt Designの裏側でも使われている信頼性の高い実装で、propsの粒度が非常に細かく設計されています。
import Slider from 'rc-slider';
import 'rc-slider/assets/index.css';
function MySlider() {
return (
<Slider
min={0}
max={100}
step={5}
defaultValue={30}
onChange={(value) => console.log('Changed:', value)}
onAfterChange={(value) => console.log('Final value:', value)}
/>
);
}
react-slider: 直感的なpropsとシンプルな構成react-slider は最小限のpropsで動作し、初心者にも分かりやすい設計です。
import ReactSlider from 'react-slider';
function MySlider() {
return (
<ReactSlider
min={0}
max={100}
step={5}
defaultValue={30}
onChange={(value) => console.log('Changed:', value)}
// onAfterChange は存在しない
/>
);
}
💡 注:
react-input-sliderは以下のような古いAPIを持ちますが、新規プロジェクトでは使用しないでください。// 非推奨:react-input-slider(使用禁止) import Slider from 'react-input-slider'; function MySlider() { return <Slider axis="x" x={50} onChange={({ x }) => console.log(x)} />; }
複数の値を同時に選択できる範囲スライダーは、日付フィルターや価格帯選択などでよく使われます。
rc-slider: 専用のRangeコンポーネントを提供rc-slider は Range コンポーネントを別途エクスポートしており、明確に分かれています。
import { Range } from 'rc-slider';
function PriceRange() {
return (
<Range
min={0}
max={1000}
defaultValue={[200, 800]}
onChange={(values) => console.log('Range:', values)}
/>
);
}
react-slider: 単一コンポーネントで範囲選択をサポートreact-slider は minValue と maxValue props で範囲選択を有効化します。
import ReactSlider from 'react-slider';
function PriceRange() {
return (
<ReactSlider
min={0}
max={1000}
defaultValue={[200, 800]}
onChange={(values) => console.log('Range:', values)}
// 内部で配列かどうかを判定
/>
);
}
縦方向スライダーは音量調節や特殊なUIで必要になることがあります。
rc-slider: vertical propで明示的に指定<Slider vertical min={0} max={100} defaultValue={50} />
react-slider: orientation propで制御<ReactSlider orientation="vertical" min={0} max={100} defaultValue={50} />
スクリーンリーダー対応やキーボード操作は、プロダクション品質のUIに必須です。
rc-slider: 完全なARIA属性(role="slider", aria-valuenow など)を自動出力。キーボード操作(矢印キー、Home/End)を標準でサポート。react-slider: 同様にARIA属性を含み、キーボードナビゲーションに対応。ariaLabel や ariaValuetext などのpropsでカスタマイズ可能。react-input-slider: ARIA属性のサポートが不完全で、現代的なアクセシビリティ基準を満たしていない可能性が高い。ブランドガイドラインに合わせて見た目を調整したい場合の柔軟性を比較します。
rc-slider: renderTrack / renderHandle で完全制御<Slider
renderTrack={(props, state) => (
<div {...props} style={{ ...props.style, backgroundColor: '#ccc' }} />
)}
renderHandle={(props) => (
<div {...props} style={{ ...props.style, width: 24, height: 24, borderRadius: '50%' }} />
)}
/>
react-slider: classNameやstyle propsで部分カスタマイズ<ReactSlider
className="horizontal-slider"
thumbClassName="custom-thumb"
trackClassName="custom-track"
/>
CSSでスタイルを上書きする方式で、JavaScriptによる動的レンダリングはサポートされていません。
rc-slider: 各ハンドルやトラックに一意の data-* 属性が付与されており、E2Eテスト(CypressやPlaywright)で簡単に要素を選択可能。react-slider: thumbClassName や trackClassName を活用してテストIDを付与できるが、動的クラス名のため少し工夫が必要。react-input-slider: テスト向けの属性がなく、DOM構造が不安定なため、テストの保守コストが高くなる。Reactの状態管理ライブラリ(Redux、Zustand、Context API)と組み合わせる際の考慮点です。
rc-slider: onAfterChange で不要な再レンダリングを抑制onChange はドラッグ中の毎フレームで呼ばれるため、頻繁な状態更新を避けたい場合に onAfterChange を使うのがベストプラクティスです。
const [value, setValue] = useState(50);
<Slider
value={value}
onChange={setValue} // プレビュー用
onAfterChange={(v) => dispatch(updateValue(v))} // 最終確定値のみ保存
/>
react-slider: onChange のみ提供 — 最適化は自前でonAfterChange が存在しないため、不要な再レンダリングを防ぐには useRef や debounce を自前で実装する必要があります。
const debouncedUpdate = useRef(debounce((v) => dispatch(updateValue(v)), 300));
<ReactSlider
value={value}
onChange={(v) => {
setValue(v);
debouncedUpdate.current(v);
}}
/>
| 要件 | 推奨パッケージ |
|---|---|
| 複雑なUI(範囲選択、縦スライダー、カスタムハンドル)が必要 | rc-slider |
| Ant Design と統合済み or 今後統合予定 | rc-slider |
| シンプルなスライダーで軽量さを重視 | react-slider |
| アクセシビリティ対応が必須 | rc-slider または react-slider(両方対応) |
| 新規プロジェクト | react-input-slider は絶対に使用しない |
rc-slider を選ぶ。機能性とメンテナンス性のバランスが最良。react-slider で十分。学習コストが低く、bundle sizeも小さい。react-input-slider を使っている場合 → 次のメジャーアップデートで rc-slider または react-slider への移行を計画してください。スライダーコンポーネントは一見単純に見えますが、アクセシビリティ、パフォーマンス、カスタマイズ性を考慮すると、ライブラリ選びは慎重に行うべきです。あなたのプロジェクトのスケールと要件に合った選択をしましょう。
rc-slider は複雑な要件(範囲選択、カスタムハンドル、縦方向スライダー、ステップ制御など)をサポートする必要がある場合に最適です。Ant Design エコシステムとの統合が求められるプロジェクトや、高いカスタマイズ性と安定したメンテナンスを重視するチーム向けです。ただし、軽量さより機能性を優先する設計なので、シンプルな用途ではオーバースペックになる可能性があります。
react-slider はバランスの取れた機能セットとクリーンなAPIを求める場合に適しています。基本的なスライダー機能(縦横切り替え、キーボード操作、ARIA属性対応)をシンプルに実装したい中規模プロジェクトに向いています。高度なカスタマイズや複雑なインタラクションが不要であれば、このパッケージが最も扱いやすい選択肢です。
react-input-slider は非推奨または未メンテナンスの可能性が高く、公式ドキュメントや最近のリリース情報が存在しません。新規プロジェクトでは使用を避けて、代わりに rc-slider や react-slider を検討すべきです。既存コードベースで使用されている場合は、将来的な移行を計画することを強く推奨します。
Slider UI component for React
npm start and then go to http://localhost:8000
Online examples: https://slider.react-component.now.sh/
import Slider from 'rc-slider';
import 'rc-slider/assets/index.css';
export default () => (
<>
<Slider />
</>
);
Please refer to #825 for information regarding usage of Range.
An example:
import Slider, { Range } from 'rc-slider';
import 'rc-slider/assets/index.css';
export default () => (
<>
<Slider range />
</>
);
![]() IE / Edge | ![]() Firefox | ![]() Chrome | ![]() Safari | ![]() Electron |
|---|---|---|---|---|
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
An extension to make Slider or Range support Tooltip on handle.
const Slider = require('rc-slider');
const createSliderWithTooltip = Slider.createSliderWithTooltip;
const Range = createSliderWithTooltip(Slider.Range);
After Range or Slider was wrapped by createSliderWithTooltip, it will have the following props:
| Name | Type | Default | Description |
|---|---|---|---|
| tipFormatter | (value: number): React.ReactNode | value => value | A function to format tooltip's overlay |
| tipProps | Object | { placement: 'top', prefixCls: 'rc-slider-tooltip', overlay: tipFormatter(value) } | A function to format tooltip's overlay |
The following APIs are shared by Slider and Range.
| Name | Type | Default | Description |
|---|---|---|---|
| className | string | '' | Additional CSS class for the root DOM node |
| min | number | 0 | The minimum value of the slider |
| max | number | 100 | The maximum value of the slider |
| id | string | '' | Unique identifier for the component, used for accessibility |
| marks | {number: ReactNode} or{number: { style, label }} | {} | Marks on the slider. The key determines the position, and the value determines what will show. If you want to set the style of a specific mark point, the value should be an object which contains style and label properties. |
| step | number or null | 1 | Value to be added or subtracted on each step the slider makes. Must be greater than zero, and max - min should be evenly divisible by the step value. When marks is not an empty object, step can be set to null, to make marks as steps. |
| vertical | boolean | false | If vertical is true, the slider will be vertical. |
| handle | (props) => React.ReactNode | A handle generator which could be used to customized handle. | |
| included | boolean | true | If the value is true, it means a continuous value interval, otherwise, it is a independent value. |
| reverse | boolean | false | If the value is true, it means the component is rendered reverse. |
| disabled | boolean | false | If true, handles can't be moved. |
| keyboard | boolean | true | Support using keyboard to move handlers. |
| dots | boolean | false | When the step value is greater than 1, you can set the dots to true if you want to render the slider with dots. |
| onBeforeChange | Function | NOOP | onBeforeChange will be triggered when ontouchstart or onmousedown is triggered. |
| onChange | Function | NOOP | onChange will be triggered while the value of Slider changing. |
| onChangeComplete | Function | NOOP | onChangeComplete will be triggered when ontouchend or onmouseup is triggered. |
| minimumTrackStyle | Object | please use trackStyle instead. (only used for slider, just for compatibility , will be deprecate at rc-slider@9.x ) | |
| maximumTrackStyle | Object | please use railStyle instead (only used for slider, just for compatibility , will be deprecate at rc-slider@9.x) | |
| handleStyle | Array[Object] | Object | [{}] | The style used for handle. (both for slider(Object) and range(Array of Object), the array will be used for multi handle following element order) |
| trackStyle | Array[Object] | Object | [{}] | The style used for track. (both for slider(Object) and range(Array of Object), the array will be used for multi track following element order) |
| railStyle | Object | {} | The style used for the track base color. |
| dotStyle | Object | (dotValue) => Object | {} | The style used for the dots. |
| activeDotStyle | Object | (dotValue) => Object | {} | The style used for the active dots. |
| Name | Type | Default | Description |
|---|---|---|---|
| defaultValue | number | 0 | Set initial value of slider. |
| value | number | - | Set current value of slider. |
| startPoint | number | undefined | Track starts from this value. If undefined, min is used. |
| tabIndex | number | 0 | Set the tabIndex of the slider handle. |
| ariaLabelForHandle | string | - | Set the aria-label attribute on the slider handle. |
| ariaLabelledByForHandle | string | - | Set the aria-labelledby attribute on the slider handle. |
| ariaRequired | boolean | - | Set the aria-required attribute on the slider handle. |
| ariaValueTextFormatterForHandle | (value) => string | - | A function to set the aria-valuetext attribute on the slider handle. It receives the current value of the slider and returns a formatted string describing the value. See WAI-ARIA Authoring Practices 1.1 for more information. |
| Name | Type | Default | Description |
|---|---|---|---|
| defaultValue | number[] | [0, 0] | Set initial positions of handles. |
| value | number[] | Set current positions of handles. | |
| tabIndex | number[] | [0, 0] | Set the tabIndex of each handle. |
| ariaLabelGroupForHandles | Array[string] | - | Set the aria-label attribute on each handle. |
| ariaLabelledByGroupForHandles | Array[string] | - | Set the aria-labelledby attribute on each handle. |
| ariaValueTextFormatterGroupForHandles | Array[(value) => string] | - | A function to set the aria-valuetext attribute on each handle. It receives the current value of the slider and returns a formatted string describing the value. See WAI-ARIA Authoring Practices 1.1 for more information. |
| count | number | 1 | Determine how many ranges to render, and multiple handles will be rendered (number + 1). |
| allowCross | boolean | true | allowCross could be set as true to allow those handles to cross. |
| pushable | boolean or number | false | pushable could be set as true to allow pushing of surrounding handles when moving a handle. When set to a number, the number will be the minimum ensured distance between handles. Example: ![]() |
| draggableTrack | boolean | false | Open the track drag. open after click on the track will be invalid. |
The Tooltip Component that keep following with content.
npm install
npm start
npm run test
npm run coverage
rc-slider is released under the MIT license.