This package is easy way to use react-virtualized (built in WindowScroller
, AutoSizer
, List
and optional of InfiniteLoader
). and use ResizeObserver
to automatically update cache of CellMeasurerCache
. (If you want to support IE, please add ResizeObserver
polyfill)
npm i react-easy-virtualized --save
Manually use of react-virtualized
package example.
import { AutoSizer, List, WindowScroller, InfiniteLoader, CellMeasurerCache, ListRowRenderer, CellMeasurer } from 'react-virtualized'; const cache = new CellMeasurerCache(); type Props = { data: AnyData[]; loadMore(): Promise<void>; hasMore: boolean; }; function App ({ data, loadMore, hasMore }: Props) { const rowCount = data.length + (hasMore ? 1 : 0); const isRowLoaded = ({ index }: { index: number }) => { return !hasMore || index < data.length; }; const rowRenderer: ListRowRenderer = params => { const item = isRowLoaded(params) ? <DataComponent data={data[params.index]} /> : <div>Loading...</div>; return ( <CellMeasurer cache={cache} parent={params.parent} columnIndex={0} rowIndex={params.index} > <div style={params.style}> {item} </div> </CellMeasurer> ); }; return ( <WindowScroller> {({ height, isScrolling, onChildScroll, scrollTop }) => ( <AutoSizer disableHeight> {({ width }) => <InfiniteLoader loadMoreRows={loadMore} isRowLoaded={isRowLoaded} rowCount={rowCount} > {({ onRowRendered, registerChild }) => ( <List onRowRendered={onRowRendered} ref={registerChild} scrollTop={scrollTop} isScrolling={isScrolling} onScroll={onChildScroll} width={width} height={height} rowHeight={cache.rowHeight} deferredMeasurementCache={cache} rowCount={rowCount} rowRenderer={rowRenderer} autoHeight /> ) </InfiniteLoader> } </AutoSizer> )} </WindowScroller> ); }
... it's to long and hard to understanding rendering. try to use react-easy-virtualized
!
import EasyVirtualized from 'react-easy-virtualized'; type Props = { data: AnyData[]; loadMore(): Promise<void>; hasMore: boolean; }; function App ({ data, loadMore, hasMore }: Props) { return ( <EasyVirtualized onLoadMore={loadMore} hasMore={hasMore} loader={<div>Loading...</div>} > {data.map(item => ( <DataComponent key={data.id} data={data} /> )} </EasyVirtualized> ); };
Just give a childrens with key
! Isn't it short and easy to understand? Let's go!
type Props = { // Want to detect parent overflow auto|scroll element. default is false (using window scroll) useParentScrollElement?: boolean; // Want to control overscan row count. default is 10 (Doc: https://github.com/bvaughn/react-virtualized/blob/master/docs/overscanUsage.md) overscanRowCount?: number; // InfiniteScroll options // pass `onLoadMore` and `hasMore` to enable infiniteScroll option onLoadMore?: () => Promise<void>; hasMore?: boolean; scrollReverse?: boolean; // if you want to use reverse scroll loader?: React.ReactElement; };
- Automatically update cache when prepended item, deleted item, resize item dom
- If resize item is outside from overscan area, will be automatically update cache when stop scroll after 3 seconds
- If you want to manually control cache, pass to ref to
EasyVirtualized
and usingupdateCache()
import { useRef, Key } from 'react'; import EasyVirtualized, { EasyVirtualizedScrollerRef } from 'react-easy-virtualized'; function App () { const scrollerRef = useRef<EasyVirtualizedScrollerRef>(null); function updateItem ({ key, index }: { key?: Key; index?: number }) { // you can update the cache by index or key. scrollerRef.current.updateCache({ key, index }); } return <EasyVirtualized ref={scrollerRef} /> }