React Custom Scrollbars
react-custom-scrollbars is a React component library designed to replace native browser scrollbars with fully customizable alternatives, offering a consistent look and feel across different browsers and devices. It prioritizes performance with `requestAnimationFrame` for smooth scrolling and supports universal rendering (SSR). Key features include auto-hide, auto-height, and extensive styling options without requiring external stylesheets. The current stable version is 4.2.1. While not on a fixed release cadence, the project has seen consistent updates in its 4.x series, primarily focusing on React compatibility and bug fixes. It differentiates itself by its focus on native-like behavior, mobile support, and complete visual control, contrasting with simpler scroll solutions or those that inject complex CSS.
Common errors
-
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
cause Attempting to use a default import instead of a named import for the Scrollbars component.fixChange `import Scrollbars from 'react-custom-scrollbars';` to `import { Scrollbars } from 'react-custom-scrollbars';`. -
Warning: Can't perform a React state update on an unmounted component.
cause This warning often occurs when asynchronous operations (e.g., debounced scroll event handlers) attempt to update state on a React component that has already been unmounted. While not specific to `react-custom-scrollbars`, it's common when attaching custom event listeners to it.fixEnsure that any state updates or external event listeners attached to the Scrollbars component or its children are properly cleaned up in the component's `componentWillUnmount` or a `useEffect` cleanup function. -
TypeError: Cannot read properties of undefined (reading 'getScrollHeight')
cause Attempting to access Scrollbars instance methods (e.g., `getScrollHeight`, `scrollToTop`) via a ref before the component has fully mounted or if the ref is not correctly assigned.fixEnsure the ref is correctly assigned to the Scrollbars component (e.g., `<Scrollbars ref={this.scrollbarsRef}>`) and accessed only after the component has mounted (e.g., in `componentDidMount` or a `useEffect` hook with a dependency array checking for ref's existence).
Warnings
- breaking Version 4.0.0 removed cursor styles from tracks and changed the default behavior for 'heightTracksWhenNotNeeded' and 'autoHeight'. Existing custom CSS or assumptions about track visibility might need adjustments.
- breaking Starting with v4.1.0, the package no longer ships its own TypeScript definition files (index.d.ts was removed). Projects using TypeScript will need to install `@types/react-custom-scrollbars` for type inference.
- gotcha The package has peer dependencies on 'react' and 'react-dom' (>=0.14.0 || >=15.0.0 || >=16.0.0). Ensure your project's React version falls within these ranges to avoid compatibility issues, especially with newer React versions not explicitly listed.
- gotcha When using the `autoHeight` prop, ensure the parent container of the Scrollbars component does not have an explicit fixed height, as this can lead to unexpected sizing or scrolling behavior. `autoHeight` is designed for content-driven height.
- gotcha For server-side rendering (SSR) environments, the `universal` prop must be set to `true` to prevent issues with `window` and `document` object access during the initial render, which can cause hydration mismatches or errors.
Install
-
npm install react-custom-scrollbars -
yarn add react-custom-scrollbars -
pnpm add react-custom-scrollbars
Imports
- Scrollbars
import Scrollbars from 'react-custom-scrollbars';
import { Scrollbars } from 'react-custom-scrollbars'; - Scrollbars (CommonJS)
const Scrollbars = require('react-custom-scrollbars').default;const { Scrollbars } = require('react-custom-scrollbars'); - Instance methods
this.scrollbars.getScrollHeight();
Quickstart
import React, { Component } from 'react';
import { Scrollbars } from 'react-custom-scrollbars';
class CustomScrollbarExample extends Component {
render() {
// Simulate dynamic content that would typically exceed container height
const longContent = Array.from({ length: 50 }).map((_, i) => (
<p key={i} style={{ marginBottom: '8px', lineHeight: '1.4' }}>
This is line {i + 1} of scrollable content. It demonstrates how{' '}
<span style={{ fontWeight: 'bold' }}>react-custom-scrollbars</span> handles overflow{' '}
with its custom scroll mechanism. The content within the Scrollbars component will be
wrapped and managed.
</p>
));
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif', maxWidth: '800px', margin: '0 auto' }}>
<h1>Custom Scrollbar Example</h1>
<p>
Below is a `Scrollbars` component configured with a fixed width and height.
The content inside will scroll using the custom scrollbars provided by the library.
</p>
<div style={{ border: '1px solid #e0e0e0', borderRadius: '4px', overflow: 'hidden' }}>
<Scrollbars style={{ width: '100%', height: 300 }}>
{longContent}
</Scrollbars>
</div>
<p style={{ marginTop: '20px' }}>
This shows the basic usage, allowing for a visually consistent scroll experience
across different browsers and operating systems, with full control over the scrollbar's appearance.
</p>
</div>
);
}
}
export default CustomScrollbarExample;