or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# React Infinite Scroller

1

2

React Infinite Scroller is a lightweight React component that provides infinite scrolling functionality for both window and element-based scroll detection. It supports customizable thresholds, reverse scrolling for chat-like interfaces, and passive event listeners for optimal performance.

3

4

## Package Information

5

6

- **Package Name**: react-infinite-scroller

7

- **Package Type**: npm

8

- **Language**: JavaScript (React component)

9

- **Installation**: `npm install react-infinite-scroller`

10

11

## Core Imports

12

13

```javascript

14

import InfiniteScroll from 'react-infinite-scroller';

15

```

16

17

For CommonJS:

18

19

```javascript

20

const InfiniteScroll = require('react-infinite-scroller');

21

```

22

23

## Basic Usage

24

25

```javascript

26

import React, { useState } from 'react';

27

import InfiniteScroll from 'react-infinite-scroller';

28

29

function MyComponent() {

30

const [items, setItems] = useState([]);

31

const [hasMore, setHasMore] = useState(true);

32

33

const loadMore = async (page) => {

34

try {

35

// Note: page starts from pageStart + 1 (so if pageStart=0, first call gets page=1)

36

const response = await fetch(`/api/items?page=${page}`);

37

const newItems = await response.json();

38

39

if (newItems.length === 0) {

40

setHasMore(false);

41

} else {

42

setItems(prevItems => [...prevItems, ...newItems]);

43

}

44

} catch (error) {

45

console.error('Failed to load items:', error);

46

}

47

};

48

49

return (

50

<InfiniteScroll

51

pageStart={0}

52

loadMore={loadMore}

53

hasMore={hasMore}

54

loader={<div className="loader" key={0}>Loading...</div>}

55

>

56

<div>

57

{items.map((item, index) => (

58

<div key={index}>{item.name}</div>

59

))}

60

</div>

61

</InfiniteScroll>

62

);

63

}

64

```

65

66

## Capabilities

67

68

### InfiniteScroll Component

69

70

Core React component that handles infinite scroll functionality with comprehensive configuration options.

71

72

```javascript { .api }

73

/**

74

* React component for infinite scrolling functionality

75

* @component

76

*/

77

function InfiniteScroll(props: InfiniteScrollProps): React.ReactElement;

78

79

interface InfiniteScrollProps {

80

/** Content to be rendered inside the scroll container (required) */

81

children: React.ReactNode;

82

83

/** Callback function triggered when more content needs to be loaded (required)

84

* @param page - Page number starting from pageStart + 1 */

85

loadMore: (page: number) => void;

86

87

/** HTML element type to render as container */

88

element?: string | React.ComponentType;

89

90

/** Whether more items are available to load

91

* When false, all scroll event listeners are automatically removed */

92

hasMore?: boolean;

93

94

/** Whether to trigger loadMore on component mount */

95

initialLoad?: boolean;

96

97

/** Whether to load content when scrolling to top (chat-like behavior) */

98

isReverse?: boolean;

99

100

/** React element to display while loading */

101

loader?: React.ReactNode;

102

103

/** Starting page number for loadMore callback */

104

pageStart?: number;

105

106

/** Ref callback to access the scroll container element

107

* Note: Called after internal ref processing for scroll detection */

108

ref?: (node: HTMLElement | null) => void;

109

110

/** Function to override default scroll parent detection */

111

getScrollParent?: () => HTMLElement;

112

113

/** Distance in pixels from scroll end to trigger loadMore */

114

threshold?: number;

115

116

/** Event listener capture option */

117

useCapture?: boolean;

118

119

/** Whether to use window scroll events or parent element events */

120

useWindow?: boolean;

121

}

122

```

123

124

**Default Props:**

125

- `element`: `'div'`

126

- `hasMore`: `false`

127

- `initialLoad`: `true`

128

- `pageStart`: `0`

129

- `ref`: `null`

130

- `threshold`: `250`

131

- `useWindow`: `true`

132

- `isReverse`: `false`

133

- `useCapture`: `false`

134

- `loader`: `null`

135

- `getScrollParent`: `null`

136

137

### Window Scroll Mode

138

139

Default behavior using window scroll events for infinite scrolling.

140

141

```javascript

142

<InfiniteScroll

143

pageStart={0}

144

loadMore={loadFunc}

145

hasMore={true}

146

loader={<div className="loader" key={0}>Loading...</div>}

147

>

148

{items}

149

</InfiniteScroll>

150

```

151

152

### Element Scroll Mode

153

154

Infinite scrolling within a specific scrollable container element.

155

156

```javascript

157

<div style={{height: '400px', overflow: 'auto'}}>

158

<InfiniteScroll

159

pageStart={0}

160

loadMore={loadFunc}

161

hasMore={true}

162

loader={<div className="loader" key={0}>Loading...</div>}

163

useWindow={false}

164

>

165

{items}

166

</InfiniteScroll>

167

</div>

168

```

169

170

### Custom Parent Element

171

172

Using a custom parent element for scroll calculations with getScrollParent.

173

174

```javascript

175

function MyComponent() {

176

const scrollParentRef = useRef(null);

177

178

return (

179

<div

180

style={{height: '400px', overflow: 'auto'}}

181

ref={scrollParentRef}

182

>

183

<div>

184

<InfiniteScroll

185

pageStart={0}

186

loadMore={loadFunc}

187

hasMore={true}

188

loader={<div className="loader" key={0}>Loading...</div>}

189

useWindow={false}

190

getScrollParent={() => scrollParentRef.current}

191

>

192

{items}

193

</InfiniteScroll>

194

</div>

195

</div>

196

);

197

}

198

```

199

200

### Reverse Scrolling (Chat Mode)

201

202

Loading content when scrolling to the top, useful for chat interfaces.

203

204

```javascript

205

<InfiniteScroll

206

pageStart={0}

207

loadMore={loadFunc}

208

hasMore={true}

209

loader={<div className="loader" key={0}>Loading...</div>}

210

isReverse={true}

211

>

212

{messages}

213

</InfiniteScroll>

214

```

215

216

### Instance Methods

217

218

#### setDefaultLoader

219

220

Sets a default loader component for all InfiniteScroll instances.

221

222

```javascript { .api }

223

/**

224

* Set a default loader for all InfiniteScroll components

225

* @param loader - React element to use as default loader

226

*/

227

setDefaultLoader(loader: React.ReactNode): void;

228

```

229

230

**Usage:**

231

```javascript

232

const infiniteScrollRef = useRef(null);

233

234

// Set default loader on component instance

235

useEffect(() => {

236

if (infiniteScrollRef.current) {

237

infiniteScrollRef.current.setDefaultLoader(

238

<div className="default-loader">Loading more items...</div>

239

);

240

}

241

}, []);

242

243

return (

244

<InfiniteScroll

245

ref={infiniteScrollRef}

246

pageStart={0}

247

loadMore={loadFunc}

248

hasMore={true}

249

>

250

{items}

251

</InfiniteScroll>

252

);

253

```

254

255

## Event Handling and Performance

256

257

The component automatically handles:

258

- **Passive event listeners**: Uses passive listeners when supported for better performance

259

- **Event cleanup**: Removes all event listeners on component unmount and when `hasMore` becomes false

260

- **Chrome optimization**: Prevents Chrome hangups with specific mousewheel handling

261

- **Scroll position management**: Maintains scroll position in reverse mode after new content loads

262

- **Page numbering**: The `loadMore` callback receives page numbers starting from `pageStart + 1`

263

264

## Common Patterns

265

266

### Loading State Management

267

268

```javascript

269

function InfiniteList() {

270

const [items, setItems] = useState([]);

271

const [hasMore, setHasMore] = useState(true);

272

const [isLoading, setIsLoading] = useState(false);

273

274

const loadMore = async (page) => {

275

if (isLoading) return; // Prevent overlapping requests

276

277

setIsLoading(true);

278

try {

279

const newItems = await fetchItems(page);

280

if (newItems.length === 0) {

281

setHasMore(false);

282

} else {

283

setItems(prev => [...prev, ...newItems]);

284

}

285

} finally {

286

setIsLoading(false);

287

}

288

};

289

290

return (

291

<InfiniteScroll

292

pageStart={0}

293

loadMore={loadMore}

294

hasMore={hasMore && !isLoading}

295

loader={<div>Loading...</div>}

296

>

297

<div>

298

{items.map((item, index) => (

299

<div key={item.id || index}>{item.content}</div>

300

))}

301

</div>

302

</InfiniteScroll>

303

);

304

}

305

```

306

307

### Custom Threshold

308

309

```javascript

310

<InfiniteScroll

311

pageStart={0}

312

loadMore={loadFunc}

313

hasMore={true}

314

threshold={100} // Trigger load when 100px from bottom

315

loader={<div>Loading...</div>}

316

>

317

{items}

318

</InfiniteScroll>

319

```

320

321

### Error Handling

322

323

```javascript

324

const loadMore = async (page) => {

325

try {

326

const newItems = await fetchItems(page);

327

setItems(prev => [...prev, ...newItems]);

328

setHasMore(newItems.length > 0);

329

} catch (error) {

330

console.error('Failed to load items:', error);

331

setHasMore(false); // Stop further loading attempts

332

}

333

};

334

```