or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-react-virtual

Hooks for virtualizing scrollable elements in React with support for rows, columns, and grids

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-virtual@3.13.x

To install, run

npx @tessl/cli install tessl/npm-react-virtual@3.13.0

0

# React Virtual

1

2

React Virtual is a React hooks library that provides efficient virtualization capabilities for scrollable elements, enabling developers to render large lists and grids with optimal performance. The library offers a single headless hook (useVirtual) that supports row, column, and grid virtualization with flexible sizing options including fixed, variable, and dynamic measurements.

3

4

## Package Information

5

6

- **Package Name**: react-virtual

7

- **Package Type**: npm

8

- **Language**: JavaScript (with TypeScript support)

9

- **Installation**: `npm install react-virtual` or `yarn add react-virtual`

10

11

## Core Imports

12

13

```javascript

14

import { useVirtual } from "react-virtual";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { useVirtual } = require("react-virtual");

21

```

22

23

## Basic Usage

24

25

```javascript

26

import React from "react";

27

import { useVirtual } from "react-virtual";

28

29

function VirtualList() {

30

const parentRef = React.useRef();

31

32

const rowVirtualizer = useVirtual({

33

size: 10000,

34

parentRef: parentRef,

35

estimateSize: React.useCallback(() => 35, []),

36

});

37

38

return (

39

<div

40

ref={parentRef}

41

style={{

42

height: "200px",

43

width: "400px",

44

overflow: "auto",

45

}}

46

>

47

<div

48

style={{

49

height: `${rowVirtualizer.totalSize}px`,

50

width: "100%",

51

position: "relative",

52

}}

53

>

54

{rowVirtualizer.items.map((virtualRow) => (

55

<div

56

key={virtualRow.index}

57

style={{

58

position: "absolute",

59

top: 0,

60

left: 0,

61

width: "100%",

62

height: `${virtualRow.size}px`,

63

transform: `translateY(${virtualRow.start}px)`,

64

}}

65

>

66

Row {virtualRow.index}

67

</div>

68

))}

69

</div>

70

</div>

71

);

72

}

73

```

74

75

## Architecture

76

77

React Virtual is built around a single, powerful hook that manages virtualization state:

78

79

- **Measurement System**: Tracks item sizes using either fixed estimates or dynamic measurements

80

- **Viewport Calculation**: Determines which items are visible based on scroll position and container size

81

- **Overscan Management**: Renders additional items beyond the visible area for smooth scrolling

82

- **Imperative Scrolling**: Provides functions to programmatically scroll to specific items or offsets

83

- **Orientation Support**: Handles both vertical (default) and horizontal virtualization

84

85

## Capabilities

86

87

### useVirtual Hook

88

89

The main virtualization hook that manages the rendering of large lists, grids, and columns with optimal performance.

90

91

```javascript { .api }

92

/**

93

* Main virtualization hook for efficient rendering of large datasets

94

* @param options - Configuration object for virtualization behavior

95

* @returns Object containing virtual items and control functions

96

*/

97

function useVirtual(options: VirtualOptions): VirtualResult;

98

99

interface VirtualOptions {

100

/** Total number of items to virtualize (required) */

101

size: number;

102

/** Reference to the scrollable parent element (required) */

103

parentRef: React.RefObject<HTMLElement>;

104

/** Function to estimate size of each item (required, must be memoized with useCallback) */

105

estimateSize: (index: number) => number;

106

/** Number of items to render beyond visible area (default: 1) */

107

overscan?: number;

108

/** Enable horizontal virtualization using width/scrollLeft (default: false) */

109

horizontal?: boolean;

110

}

111

112

interface VirtualResult {

113

/** Array of currently visible virtual items */

114

items: VirtualItem[];

115

/** Total size of all virtualized content in pixels */

116

totalSize: number;

117

/** Function to scroll to a specific pixel offset */

118

scrollToOffset: (offset: number) => void;

119

/** Function to scroll to a specific item index */

120

scrollToIndex: (index: number) => void;

121

}

122

123

interface VirtualItem {

124

/** Zero-based index of the item */

125

index: number;

126

/** Starting position in pixels */

127

start: number;

128

/** Item size in pixels */

129

size: number;

130

/** Ending position in pixels */

131

end: number;

132

/** Ref callback for dynamic measurement */

133

measureRef: (element: HTMLElement | null) => void;

134

}

135

```

136

137

**Usage Patterns:**

138

139

**Row Virtualization (Vertical Lists):**

140

```javascript

141

const rowVirtualizer = useVirtual({

142

size: 10000,

143

parentRef: parentRef,

144

estimateSize: React.useCallback(() => 35, []),

145

overscan: 5,

146

});

147

```

148

149

**Column Virtualization (Horizontal Lists):**

150

```javascript

151

const columnVirtualizer = useVirtual({

152

horizontal: true,

153

size: 1000,

154

parentRef: parentRef,

155

estimateSize: React.useCallback(() => 100, []),

156

overscan: 5,

157

});

158

```

159

160

**Grid Virtualization (2D Virtualization):**

161

```javascript

162

// Use two separate hooks for rows and columns

163

const rowVirtualizer = useVirtual({

164

size: 10000,

165

parentRef: parentRef,

166

estimateSize: React.useCallback(() => 35, []),

167

overscan: 5,

168

});

169

170

const columnVirtualizer = useVirtual({

171

horizontal: true,

172

size: 10000,

173

parentRef: parentRef,

174

estimateSize: React.useCallback(() => 100, []),

175

overscan: 5,

176

});

177

178

// Render grid by mapping over both virtualizers

179

return (

180

<div ref={parentRef} style={{ height: "500px", width: "500px", overflow: "auto" }}>

181

<div

182

style={{

183

height: `${rowVirtualizer.totalSize}px`,

184

width: `${columnVirtualizer.totalSize}px`,

185

position: "relative",

186

}}

187

>

188

{rowVirtualizer.items.map((virtualRow) => (

189

<React.Fragment key={virtualRow.index}>

190

{columnVirtualizer.items.map((virtualColumn) => (

191

<div

192

key={virtualColumn.index}

193

style={{

194

position: "absolute",

195

top: 0,

196

left: 0,

197

width: `${virtualColumn.size}px`,

198

height: `${virtualRow.size}px`,

199

transform: `translateX(${virtualColumn.start}px) translateY(${virtualRow.start}px)`,

200

}}

201

>

202

Cell {virtualRow.index}, {virtualColumn.index}

203

</div>

204

))}

205

</React.Fragment>

206

))}

207

</div>

208

</div>

209

);

210

```

211

212

**Dynamic Measurement:**

213

```javascript

214

// For items with unknown sizes, use measureRef for runtime measurement

215

{rowVirtualizer.items.map((virtualRow) => (

216

<div

217

key={virtualRow.index}

218

ref={virtualRow.measureRef}

219

style={{

220

position: "absolute",

221

top: 0,

222

left: 0,

223

width: "100%",

224

transform: `translateY(${virtualRow.start}px)`,

225

}}

226

>

227

Content with dynamic height...

228

</div>

229

))}

230

```

231

232

**Imperative Scrolling:**

233

```javascript

234

// Scroll to specific item

235

const scrollToItem = (index) => {

236

rowVirtualizer.scrollToIndex(index);

237

};

238

239

// Scroll to specific offset

240

const scrollToTop = () => {

241

rowVirtualizer.scrollToOffset(0);

242

};

243

```

244

245

### Key Features

246

247

- **Performance Optimized**: Only renders visible items plus overscan, dramatically reducing DOM nodes

248

- **Flexible Sizing**: Supports fixed, variable, and dynamic item sizing

249

- **Multi-directional**: Handles vertical (default) and horizontal virtualization

250

- **Grid Support**: Combine row and column virtualizers for 2D grids

251

- **Smooth Scrolling**: Configurable overscan prevents visual gaps during fast scrolling

252

- **Imperative Control**: Programmatic scrolling to specific items or positions

253

- **Framework Agnostic**: Pure React hook with no additional dependencies beyond React

254

- **TypeScript Ready**: Full type definitions for enhanced development experience

255

256

### Error Handling

257

258

The hook expects:

259

- `estimateSize` to be memoized with `React.useCallback()` to prevent unnecessary re-calculations

260

- `parentRef` to reference an element with `overflow: auto` or `overflow: scroll`

261

- `size` to be a positive integer representing the total number of items

262

263

If these requirements aren't met, the virtualization may not work correctly or performance may be degraded.