React Segmented Controls
rc-segmented is a foundational React component for building highly customizable segmented controls, extensively utilized within the Ant Design ecosystem. It presents choices as a group of buttons where typically only one can be active at a time, akin to a radio group. The component supports various data types for options (strings, numbers, or objects), robust `onChange` event handling, and manages selection state. Currently stable at version `2.7.1`, the package maintains a moderate release cadence, focusing on bug fixes, performance enhancements, and crucial accessibility improvements. While `rc-segmented` is the primary package, a newer scoped version, `@rc-component/segmented`, sometimes receives parallel updates, which can be a point of confusion for developers. Key differentiators include its deep integration with Ant Design's principles, a strong emphasis on accessibility, and a clear, functional API for managing segmented choices efficiently within React applications.
Common errors
-
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
cause Incorrect import of the Segmented component; it is a default export.fixChange `import { Segmented } from 'rc-segmented';` to `import Segmented from 'rc-segmented';` -
Module not found: Error: Can't resolve 'rc-segmented/assets/index.css' in '...' or similar CSS loading errors.
cause The CSS stylesheet for the component was not found or incorrectly imported.fixEnsure `import 'rc-segmented/assets/index.css';` is present in your application's entry point or component, and your build tool (e.g., Webpack, Vite) is configured to handle CSS imports. -
TypeError: Cannot read properties of undefined (reading 'map') or 'options' prop is not an array.
cause The `options` prop provided to the `Segmented` component is either missing or not a valid array.fixEnsure the `options` prop is always an array, for example: `<Segmented options={['Option 1', 'Option 2']} />`.
Warnings
- breaking The `onChange` API changed significantly in versions `v2.0.0+`. Ensure your callback signature matches the new `(value: string | number) => void` type, as it now receives only the selected value.
- gotcha The component requires explicit CSS imports for styling. If the component appears unstyled, you likely forgot to import `rc-segmented/assets/index.css`.
- gotcha There exist two related packages, `rc-segmented` and `@rc-component/segmented`, which receive similar updates. Ensure you are consistently using the intended package, as mixing them or using the wrong one could lead to unexpected behavior or versioning conflicts.
- gotcha Older versions of `rc-segmented` (prior to `v2.7.1`) may have had accessibility shortcomings, particularly concerning keyboard navigation and ARIA attributes. These issues have been progressively addressed in recent updates.
Install
-
npm install rc-segmented -
yarn add rc-segmented -
pnpm add rc-segmented
Imports
- Segmented
import { Segmented } from 'rc-segmented';import Segmented from 'rc-segmented';
- Styles
import 'rc-segmented/index.css';
import 'rc-segmented/assets/index.css';
- SegmentedOption (Type)
import type { SegmentedOption } from 'rc-segmented';
Quickstart
import Segmented from 'rc-segmented';
import 'rc-segmented/assets/index.css';
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
const App = () => {
const [value, setValue] = useState('Antd');
const handleValueChange = (newValue: string | number) => {
console.log('Selected value:', newValue);
setValue(newValue);
};
return (
<div style={{ padding: '20px' }}>
<h1>rc-segmented Demo</h1>
<Segmented
options={['Antd', 'Antv', 'Egg.js', { label: 'Pro', value: 'Pro', disabled: true } ]}
value={value}
onChange={handleValueChange}
/>
<p>Currently selected: {value}</p>
</div>
);
};
const mountNode = document.getElementById('root');
if (mountNode) {
const root = createRoot(mountNode);
root.render(<App />);
} else {
console.error("Mount node with ID 'root' not found. Please ensure an element with id='root' exists in your HTML.");
}