Giter Club home page Giter Club logo

react-viewport-list's Introduction

React ViewPort List

NPM version typescript NPM license NPM total downloads NPM monthly downloads

If your application renders long lists of data (hundreds or thousands of rows), we recommended using a technique known as β€œwindowing”. This technique only renders a small subset of your rows at any given time, and can dramatically reduce the time it takes to re-render the components as well as the number of DOM nodes created.

- React.js documentation

πŸ“œ Virtualization for lists with dynamic item size

React Component that render only items in viewport

Features πŸ”₯

  • Simple API like .map()
  • Created for dynamic item height/width (if you don't know item size)
  • Works perfectly with Flexbox (unlike other libraries with pisition: absolute)
  • Supports scroll to index
  • Supports initial index
  • Supports vertical ↕ and horizontal ↔ lists️️
  • Tiny (<2kb minified+gzipped)

Try 100k list demo

Getting Started

  • Installation:

    npm install --save react-viewport-list
  • Basic Usage:

    import { useRef } from 'react';
    import ViewportList from 'react-viewport-list';
    
    const ItemsList = ({ items }) => {
        const ref = useRef(null);
    
        return (
            <div className="scroll-container" ref={ref}>
                <ViewportList viewportRef={ref} items={items} itemMinSize={40} margin={8}>
                    {(item) => (
                        <div key={item.id} className="item">
                            {item.title}
                        </div>
                    )}
                </ViewportList>
            </div>
        );
    };
    
    export default ItemsList;

Props

name type default description
viewportRef MutableRefObject required Viewport ref object
items Array [] Array of items
itemMinSize number required Item min height (or min width for 'x' axis) in px
margin number 0 Item margin bottom (or margin right for 'x' axis) in px.
You should still set margin-bottom (or margin-right for 'x' axis) in item styles
overscan number 1 Count of "overscan" items
axis 'y' / 'x' 'y' Scroll axis
'y' - vertical, 'x' - horizontal
initialIndex number -1 Initial index of item in viewport
initialAlignToTop boolean / ScrollIntoViewOptions true scrollIntoView second argument.
Used with initialIndex
initialOffset number 0 Offset after scrollIntoView.
Used with initialIndex
children (item: any, index: number) => ReactNode required Item render function.
Similar to .map() callback

Methods

  • scrollToIndex

    Params

    name type default description
    index number -1 Item index for scroll
    alignToTop boolean / ScrollIntoViewOptions true scrollIntoView second argument
    offset number 0 Offset after scrollIntoView

    Usage

    import { useRef } from 'react';
    import ViewportList from 'react-viewport-list';
    
    const ItemsList = ({ items }) => {
        const ref = useRef(null);
        const listRef = useRef(null);
    
        return (
            <div className="scroll-container" ref={ref}>
                <ViewportList ref={listRef} viewportRef={ref} items={items} itemMinSize={40} margin={8}>
                    {(item) => (
                        <div key={item.id} className="item">
                            {item.title}
                        </div>
                    )}
                </ViewportList>
                <button className="up-button" onClick={() => listRef.current.scrollToIndex(0)} />
            </div>
        );
    };
    
    export default ItemsList;

Performance

If you have performance issues, you can add will-change: transform to a scroll container.

You should remember that in some situations will-change: transform can cause performance issues not fixed them.

.scroll-container {
    will-change: transform;
}

Limitations

  • margin

    You should use only margin-bottom (or margin-right for 'x' axis) for items, and provide it to ViewportList props. Don't use margin-top (or margin-left for 'x' axis)

    .item {
        margin-bottom: 8px;
    }

Advanced Usage

  • Grouping

    ViewportList render Fragment with items in viewport

    import { useRef } from 'react';
    import ViewportList from 'react-viewport-list';
    
    const ItemsList = ({ keyItems, items }) => {
        const ref = useRef(null);
    
        return (
            <div className="scroll-container" ref={ref}>
                <span className="group-title">{'Key Items'}</span>
                <ViewportList viewportRef={ref} items={keyItems} itemMinSize={60} margin={8}>
                    {(item) => (
                        <div key={item.id} className="key-item">
                            {item.title}
                        </div>
                    )}
                </ViewportList>
                <span className="group-title">{'Items'}</span>
                <ViewportList viewportRef={ref} items={items} itemMinSize={40} margin={8}>
                    {(item) => (
                        <div key={item.id} className="item">
                            {item.title}
                        </div>
                    )}
                </ViewportList>
            </div>
        );
    };
    export default ItemsList;
  • Sorting

    You can use React Sortable HOC

    import { useRef } from 'react';
    import { SortableContainer, SortableElement } from 'react-sortable-hoc';
    import ViewportList from 'react-viewport-list';
    
    const SortableList = SortableContainer(({ innerRef, ...rest }) => <div {...rest} ref={innerRef} />);
    
    const SortableItem = SortableElement((props) => <div {...props} />);
    
    const ItemsList = ({ items, onSortEnd }) => {
        const ref = useRef(null);
    
        return (
            <SortableList innerRef={ref} className="scroll-container" onSortEnd={onSortEnd}>
                <ViewportList viewportRef={ref} items={items} itemMinSize={40} margin={8}>
                    {(item, index) => (
                        <SortableItem key={index} index={index} className="item">
                            {item.title}
                        </SortableItem>
                    )}
                </ViewportList>
            </SortableList>
        );
    };
    
    export default ItemsList;

react-viewport-list's People

Contributors

oleggrishechkin avatar dependabot[bot] avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.