React Split
react-split is a React component that enables the creation of resizable split views in web applications. It functions as a lightweight, declarative wrapper around the core Split.js library. Developers define child components within a `<Split>` container, which are then rendered as resizable panes. The current stable version is 2.0.14, with an active release cadence focused on bug fixes and minor feature enhancements. Its primary strengths include ease of use, minimal overhead, and direct exposure of Split.js options via React props, allowing for straightforward integration of flexible, resizable layouts. The package also ships with full TypeScript type definitions.
Common errors
-
Layout breaks or panels disappear when resizing to very small values
cause The `sizes` prop or subsequent drag operations result in panel sizes smaller than the `minSize` or the implicit size required by the gutters, leading to an invalid layout state.fixSet a robust `minSize` prop (e.g., `minSize={50}`) and ensure initial `sizes` are valid. Upgrade to `react-split@>=1.5.7` to benefit from fixes related to low `sizes` values. -
Split panes do not appear or are misaligned when component is initially hidden
cause The `<Split>` component was mounted while its container (or itself) had `display: none`, preventing it from accurately calculating initial dimensions.fixUpdate to `react-split@>=1.5.9`. Alternatively, ensure the component is visible upon mounting, or trigger a re-render/resize operation when the container becomes visible. -
TypeError: Cannot destructure property 'Split' of 'react_split__WEBPACK_IMPORTED_MODULE_X___default.a' as it is undefined.
cause This error occurs when attempting to use a named import for `Split` (e.g., `import { Split } from 'react-split'`) while the library provides it as a default export.fixCorrect the import statement to use the default import: `import Split from 'react-split'`. -
TypeScript error: Module '"react-split"' has no exported member 'SplitProps'.
cause Incorrect import syntax for TypeScript types, often trying to import a type as a value or without the `type` keyword.fixUse `import type { SplitProps } from 'react-split'` for importing the type definition.
Warnings
- breaking Version 2.0.0 introduced internal changes related to `React.Children.toArray`, which, while intended to fix underlying issues, might subtly alter behavior in complex scenarios involving children manipulation. No direct API changes were announced, but custom rendering logic around children may need review.
- gotcha Passing very small `sizes` values (e.g., 0) or values that calculate to less than the `gutterSize` can cause layout issues or panels to disappear, especially if `minSize` is not adequately configured.
- gotcha Split views that are initially rendered in a hidden state (e.g., via `display: none` CSS) may fail to correctly initialize their dimensions and appear broken or unresizable when later revealed.
- gotcha Prior to version 1.5.6, minor discrepancies existed in the documentation and actual behavior of cursor settings (`col-resize`, `row-resize`).
- gotcha Version 1.5.4 introduced a bug that specifically affected dragging functionality on mobile devices.
Install
-
npm install react-split -
yarn add react-split -
pnpm add react-split
Imports
- Split
import { Split } from 'react-split'import Split from 'react-split'
- SplitProps
import { SplitProps } from 'react-split'import type { SplitProps } from 'react-split' - Split (CommonJS)
const { Split } = require('react-split')const Split = require('react-split')
Quickstart
import React from 'react';
import Split from 'react-split';
// Dummy components for demonstration purposes
const PaneA = () => (
<div style={{ background: '#f0f0f0', padding: '20px', height: '100%', overflow: 'auto' }}>
<h2>Pane A</h2>
<p>This is the content for the first resizable pane. It starts at 25% of the container width.</p>
<p>You can adjust its size by dragging the splitter.</p>
</div>
);
const PaneB = () => (
<div style={{ background: '#e0e0f0', padding: '20px', height: '100%', overflow: 'auto' }}>
<h2>Pane B</h2>
<p>This is the content for the second resizable pane. It starts at 75% of the container width.</p>
<p>The `minSize` prop ensures panes don't shrink below a specified pixel value.</p>
</div>
);
function App() {
return (
<div style={{ height: '500px', width: '80%', margin: '50px auto', display: 'flex', border: '1px solid #ddd', borderRadius: '4px', overflow: 'hidden' }}>
<Split
sizes={[25, 75]}
minSize={100}
expandToMin={false}
gutterSize={10}
gutterAlign="center"
snapOffset={30}
dragInterval={1}
direction="horizontal"
cursor="col-resize"
className="split-container"
elementStyle={(dimension, elementSize, gutterSize, index) => ({
flexBasis: `calc(${elementSize}% - ${gutterSize}px)`
})}
gutterStyle={(dimension, gutterSize, index) => ({
flexBasis: `${gutterSize}px`
})}
onDragStart={() => console.log('Drag started')}
onDragEnd={(sizes) => console.log('Drag ended with sizes:', sizes)}
>
<PaneA />
<PaneB />
</Split>
</div>
);
}
export default App;