• Stars
    star
    141
  • Rank 259,971 (Top 6 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A brutally simple react infinite scroll component

React Simple Infinite Scroll

A brutally simple infinite scroll helper component.

Install

npm install react-simple-infinite-scroll --save

Usage

This component uses a "sentinel" div (with a React ref) that calls getBoundingClientRect() to measure its position and fire off a callback when it becomes visible again. Note: this package eventually becomes somewhat inefficient on very very very large lists because it keeps adding nodes to the DOM. However, this package is extremely valuable for situations when a windowing technique is not possible and when a user is going to realistically scroll a few hundred rows (and not thousands of rows).

Why not use windowing (react-virtualized)?

If you can, you probably should. However, windowing only works when you know the total number of items in the result set ahead of time. This isn't always possible. For example, let's say you have a MongoDB database where you cannot efficiently return the total number of documents in a given query. All your API returns is a cursor (so you can know is if there is another page or not). While this would prevent you from using windowing/react-virtualized, react-simple-infinite-scroll will work just fine.

The Gist

<InfiniteScroll
  throttle={100}
  threshold={300}
  isLoading={this.state.isLoading}
  hasMore={!!this.state.cursor}
  onLoadMore={this.loadMore}
>
  {this.state.myArrayOfItems.map(item => <div>{/* ... */}</div>)}
</InfiniteScroll>
<InfiniteScroll
  throttle={100}
  threshold={300}
  isLoading={this.state.isLoading}
  hasMore={!!this.state.cursor}
  onLoadMore={this.loadMore}
  render={({ sentinel }) => (
    <section>
      {this.state.myArrayOfItems.map(item => <div>{/* ... */}</div>)}
      {sentinel}
    </section>
  )}
/>
// Small react-redux pseudocode
// `storeData` is information extracted from the store
const MyComponent = ({ sentinel, storeData }) => (
  <section>
    {storeData.entities}
    {sentinel}
  </section>
);

const ConnectedComponent = connect(/* ... */)(MyComponent);

<InfiniteScroll
  throttle={100}
  threshold={300}
  isLoading={storeData.isLoading}
  hasMore={storeData.hasMore}
  onLoadMore={() => boundActions.fetchMoreEntities(storeData.cursor)}
  component={ConnectedComponent}
/>

Full Example

import React from 'react'
import { InfiniteScroll } from 'react-simple-infinite-scroll'

export class MyInfiniteScrollExample extends React.Component {
  state = {
    items: [],
    isLoading: true,
    cursor: 0
  }

  componentDidMount() {
    // do some paginated fetch
    this.loadMore()
  }

  loadMore = () => {
    this.setState({ isLoading: true, error: undefined })
    fetch(`https://api.example.com/v1/items?from=${this.state.cursor}`)
      .then(res => res.json())
      .then(
        res => {
          this.setState(state => ({
            items: [...state.items, ...res.items],
            cursor: res.cursor,
            isLoading: false
          }))
        },
        error => {
          this.setState({ isLoading: false, error })
        }
    )
  }

  render() {
    return (
      <div>
        <InfiniteScroll
          throttle={100}
          threshold={300}
          isLoading={this.state.isLoading}
          hasMore={!!this.state.cursor}
          onLoadMore={this.loadMore}
        >
          {this.state.items.length > 0
            ? this.state.items.map(item => (
                <MyListItem key={item.id} title={item.title} />
              ))
            : null}
        </InfiniteScroll>
        {this.state.isLoading && (
          <MyLoadingState />
        )}
      </div>
    )
  }
}

API Reference

Props

hasMore: boolean

Required

Specifies if there are more entities to load.

isLoading: boolean

Required

When true, onLoadMore() will not be executed on scroll.

onLoadMore: () => void

Required

Called when the user has scrolled all the way to the end. This happens when the sentinel has reached the threshold.

threshold?: number

Scroll threshold. Number of pixels before the sentinel reaches the viewport to trigger onLoadMore().

throttle?: number = 64

Defaults to 64. Scroll handler will be executed at most once per the number of milliseconds specified.

Warning: Making this number closer to zero can decrease performance due to a force reflow caused by getBoundingClientRect(), see more properties that can cause this issue in this gist by Paul Irish.

render?: (props: ScrollProps) => React.ReactNode

Callback used for convenient inline rendering and wrapping. Arguments passed Object: { sentinel, children }. Use this if you have a more complex layout where the sentinel needs to be injected.

Warning: The sentinel must be rendered (injected into the DOM) in order for this library to work properly, failing to do so will result in errors and unexpected side effects.

component?: React.ComponentType<ScrollProps>

React component. Similar to the render() prop, this component will receive Object: { sentinel, children } as props. Note that render() prop has precedence over this property, meaning that if both are present, component will not be rendered.

Warning: The sentinel must be rendered (injected into the DOM) in order for this library to work properly, failing to do so will result in errors and unexpected side effects.

Alternatives

Author

Contributors

jared palmer
jared palmer
๐Ÿ’ป ๐Ÿ“– ๐Ÿ’ก
pablo garcia
pablo garcia
๐Ÿ’ป ๐Ÿ“– ๐Ÿ’ก

This project follows the all-contributors specification.

More Repositories

1

formik

Build forms in React, without the tears ๐Ÿ˜ญ
TypeScript
33,930
star
2

tsdx

Zero-config CLI for TypeScript package development
JavaScript
11,268
star
3

razzle

โœจ Create server-rendered universal JavaScript applications with no configuration
JavaScript
11,102
star
4

backpack

๐ŸŽ’ Backpack is a minimalistic build system for Node.js projects.
JavaScript
4,470
star
5

the-platform

Web. Components. ๐Ÿ˜‚
TypeScript
4,404
star
6

after.js

Next.js-like framework for server-rendered React apps built with React Router
TypeScript
4,129
star
7

react-fns

Browser API's turned into declarative React components and HoC's
TypeScript
3,731
star
8

awesome-react-render-props

Awesome list of React components with render props
1,367
star
9

cypress-image-snapshot

Catch visual regressions in Cypress
JavaScript
887
star
10

presspack

๐Ÿ’ป Wordpress like it's 2022 with Webpack and Docker
JavaScript
689
star
11

react-parcel-example

Minimum viable React app with Parcel Bundler
JavaScript
482
star
12

minimum-viable-saas

A multi-tier membership SaaS in less than 500 lines of code w/Stripe and Firebase
JavaScript
444
star
13

formik-persist

๐Ÿ’พ Persist and rehydrate a Formik form to localStorage
TypeScript
375
star
14

mutik

A tiny (495B) immutable state management library based on Immer
TypeScript
325
star
15

typescript

TypeScript coding guidelines & configs for Formik
JavaScript
283
star
16

react-conf-2018

React Conf 2018 Source Code for "Moving to Suspense" Demo
JavaScript
227
star
17

react-email-workflow

Newsletter design tool
JavaScript
175
star
18

tsdx-monorepo

A really good starting point for your next React x TypeScript monorepo
TypeScript
175
star
19

formik-effect

Declarative component for managing side-effects in Formik forms. 580 bytes
TypeScript
166
star
20

formover

Build forms that pop bottles ๐Ÿพwith Formik and React Popper
TypeScript
160
star
21

react-persist

๐Ÿ’พ Persist and rehydrate React state to localStorage.
JavaScript
124
star
22

nextra-blank-custom-theme

A forkable Next.js site w/ a blank custom Nextra theme (w/Tailwind)
JavaScript
117
star
23

hyperhue

๐ŸŒˆ A fun HyperTerm theme that responds to your Philips Hue lights
JavaScript
103
star
24

reason-react-native-web-example

Razzle + Reason-React + React-Native-Web. Damn that's a lot of R's.
Reason
100
star
25

disco.chat

Add real-time ephemeral chat to any webpage.
TypeScript
96
star
26

react-router-nextjs-like-data-fetching

Demonstrating React Router 4's SSR awesomeness
JavaScript
89
star
27

dotfiles

My setup
Shell
52
star
28

razzle-react-vue-elm-php-lol

๐Ÿ”ฅ Blazing fast Razzle app with React, Vue, PHP, and Elm + HMR
JavaScript
49
star
29

formik-alicante

Formik slides & demos from React Alicante
JavaScript
46
star
30

codemods

Collection of codemods for TypeScript and JavaScript codebases
JavaScript
43
star
31

react-suspense-playground

Stock Market News app w/ React Suspense
JavaScript
43
star
32

razzle-unrouted

Blazingly fast server-rendered MVC Webapps with Preact and Webpack
JavaScript
42
star
33

nextjs-langchain-example

Demo of using LangChain.js with Next.js and Vercel Edge Functions (to stream the response)
TypeScript
41
star
34

framer-electron-preview

Quickly run Framer prototypes within Electron.
JavaScript
35
star
35

country-fns

๐ŸŒ Useful country data for forms and stuff.
JavaScript
35
star
36

squeezy

1 kB React component for accessible accordions / collapse UI
TypeScript
30
star
37

TIL

๐Ÿ“–Trying to document some of my learnings
30
star
38

react-europe-2019

Slides and demo app from my keynote
JavaScript
29
star
39

jpjs

Some TypeScript utils
TypeScript
21
star
40

emotion-jsxstyle

jsxstyle primitives powered by emotion
JavaScript
20
star
41

react-router-suspense-demo

React Suspense x React Router Exploration
JavaScript
17
star
42

nextjs-route-handler-email

Experimenting with react.email and Next.js 13 Route Handlers
TypeScript
16
star
43

react-snippets

My React snippets for JavaScript and TypeScript
13
star
44

jaredpalmer.github.io

TypeScript
12
star
45

framer-router

A little routing solution for Framer.js
CoffeeScript
11
star
46

thinkaboutthis.fm

Source code for thinkaboutthis.fm
TypeScript
11
star
47

formik-bloomberg-talk

Slides and examples from my talk at Bloomberg on October 31, 2019
JavaScript
10
star
48

jaredpalmer-vscode-extensionpack

All of my VS Code extensions .... in one extension pack
9
star
49

electron-starter

A minimal Electron starter
JavaScript
8
star
50

babel-preset-react-ts

Create React App's Babel 7 Preset, plus TypeScript
JavaScript
7
star
51

noirny

Website for Noir New York (formerly the lately). Opening 11/21/19
TypeScript
7
star
52

jest-jsxstyle

๐Ÿƒ Jest utilities for JSXStyle
JavaScript
6
star
53

flask-vercel

Python
6
star
54

jaredpalmer

it me.
5
star
55

saas-subdomain-nginx-node-docker

Example setup of SaaS-like user subdomains using Express, NGINX, and Docker Compose
JavaScript
5
star
56

juice.now.sh

Automattic's Juice CSS inliner as a microservice
HTML
4
star
57

datocms-next-js-blog-demo-9687

JavaScript
4
star
58

react-error-overlay-razzle-bug

JavaScript
3
star
59

glamor-jsxstyle

Future home of glamor-jsxstyle
JavaScript
3
star
60

reactnyc-formik

๐Ÿ“ˆ Formik presentation at the August React NYC meetup @Spotify
JavaScript
3
star
61

bf-solid-addons

Helpful addons to Buzzfeed's Solid CSS Framework
CSS
2
star
62

codesandbox-template-next.js

Next.js template for CodeSandbox Projects
TypeScript
2
star
63

framer-electron

Prototype desktop apps with Framer.js and Electron with your own editor.
JavaScript
2
star
64

formik-docs

WIP. Formik docs website
TypeScript
2
star
65

oss-deck

JavaScript
1
star
66

downshift-razzle-bug

JavaScript
1
star
67

next-back-button-error

JavaScript
1
star
68

flask-pipenv-example

Python
1
star
69

os-today

A list a of the GitHub repos you should be using.
JavaScript
1
star
70

blocks

TypeScript
1
star
71

ci-info

Go
1
star
72

hyperneon

Hyperterm theme that rotates neon colors
JavaScript
1
star