rc-menu: Core React Menu Component
rc-menu is a foundational, unstyled React UI component designed for building highly customizable and accessible hierarchical menus. It provides the core logic and composable primitives like `Menu`, `SubMenu`, and `MenuItem`, offering developers extensive control over styling and behavior. While widely adopted, the `rc-menu` package, currently at version `9.16.1`, is in a maintenance-only state with its last publish over a year ago. Active development and new features have migrated to the `@rc-component/menu` package (latest v1.2.0), which is the recommended choice for new projects and for existing users looking for ongoing support and enhancements. This component is often used as a base for more opinionated UI libraries, such as Ant Design's menu, due to its low-level control.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'SubMenu')
cause Attempting to access named exports like `SubMenu` or `MenuItem` as properties of a CommonJS `require` call without proper interop handling.fixIf using CommonJS, explicitly destructure the exports or access them as properties of the default export, e.g., `const { SubMenu, MenuItem } = require('rc-menu');` or `const Menu = require('rc-menu'); const SubMenu = Menu.SubMenu;`. -
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause This error often indicates a mismatch in React versions or multiple instances of React being loaded, common in complex monorepos or when peer dependencies are not correctly resolved.fixCheck your `node_modules` for duplicate React installations. Ensure that `react` and `react-dom` peer dependencies are correctly installed and that only one version of React is bundled. Use `npm ls react` or `yarn why react` to diagnose. -
Module not found: Error: Can't resolve 'rc-menu/assets/index.css'
cause The main stylesheet for `rc-menu` is not found, typically because it wasn't explicitly imported or your build system isn't configured to handle CSS imports.fixAdd `import 'rc-menu/assets/index.css';` to your entry point or main component. Ensure your bundler (e.g., Webpack, Vite) has appropriate loaders (like `css-loader` and `style-loader`) configured to process CSS files.
Warnings
- breaking The `rc-menu` package has been renamed and its active development has moved to `@rc-component/menu`. While `rc-menu` (v9.16.1) is still available, it is effectively deprecated and will not receive new features or significant updates.
- gotcha `rc-menu` is a low-level, unstyled component. It provides functionality but no default visual styling. Without importing a CSS file or applying custom styles, the menu will appear as raw HTML elements.
- gotcha Incorrect React peer dependency versions can lead to runtime errors or unexpected behavior. `rc-menu` requires specific React versions.
- gotcha When migrating from `rc-menu` to `@rc-component/menu`, internal dependencies like `rc-overflow` have also been renamed to `@rc-component/overflow`. Direct imports or assumptions about these sub-packages might break.
Install
-
npm install rc-menu -
yarn add rc-menu -
pnpm add rc-menu
Imports
- Menu
const Menu = require('rc-menu');import Menu from 'rc-menu';
- SubMenu
import SubMenu from 'rc-menu/lib/SubMenu';
import { SubMenu } from 'rc-menu'; - MenuItem
import { Item } from 'rc-menu';import { MenuItem } from 'rc-menu';
Quickstart
import React from 'react';
import ReactDOM from 'react-dom/client';
import Menu, { SubMenu, MenuItem } from 'rc-menu';
import 'rc-menu/assets/index.css'; // Don't forget to import basic styles if needed
const App = () => (
<div>
<h2>Basic rc-menu Example</h2>
<Menu style={{ width: 200, border: '1px solid #ddd' }}>
<MenuItem key="1">Option 1</MenuItem>
<SubMenu key="sub1" title="Submenu">
<MenuItem key="2-1">Sub-option 2-1</MenuItem>
<MenuItem key="2-2">Sub-option 2-2</MenuItem>
</SubMenu>
<MenuItem key="3" disabled>Disabled Option 3</MenuItem>
</Menu>
</div>
);
const container = document.getElementById('root');
if (container) {
const root = ReactDOM.createRoot(container);
root.render(<App />);
} else {
console.error("Root element not found. Please ensure a div with id 'root' exists in your HTML.");
}