Skip to content
phola edited this page Jan 13, 2017 · 38 revisions

Status: Released

This describes my plans for react-virtualized version 7 (currently in progress as PR #206). I welcome input from the community so please feel free to comment on the PR if you think certain features should (or should not) be included in the next upcoming major release.

I hope to provide jscodeshift mods to make the transition from 6.x to 7.x simpler. Doing this enables me to make a changes I've wanted to make for a while but didn't for fear of causing too much churn for library users. I haven't written codemods before though and I would welcome submissions from anyone willing to help.

Backwards incompatible changes

Clean up property names (codemod)

This project started as a drop-in replacement for fixed-data-table so I mimicked their property names. I find a few of them awkward though so I plan to clean them up in the next release. Here's a list of the ones I intend to change:

Components Old Name New Name
ArrowKeyStepper , Grid columnsCount columnCount
Grid overscanColumnsCount overscanColumnCount
FlexColumn cellClassName className
FlexTable, Grid, VirtualScroll overscanRowsCount overscanRowCount
Collection, Grid renderCell cellRenderer
Grid renderCellRanges cellRangeRenderer
ArrowKeyStepper, FlexTable, Grid, InfiniteLoader, VirtualScroll rowsCount rowCount

Use named function arguments

Named function arguments are often simpler and more future-proof than the more traditional approach. Over time I've trended more towards using these (eg. onSectionRendered, onScroll, etc) but a few of the originals (those based on fixed-data-table) don't follow this pattern. This makes it harder to update them (eg. to add a new parameter) and it makes them more confusing to use (eg. which order do the params appear in? What if I only care about the first and last param?).

Note that I also plan to methods that previously accepted only a single index parameter (eg. cellRenderer, isRowLoaded) because it would be more consistent and it would allow me to potentially pass other useful information to those methods in the future without requiring a major release.

Here's a list of the ones I intend to change:

Function Old Name New Name
Collection.onSectionRendered (indices: Array<number>): void ({ indices: Array<number> }): void
Collection.cellRenderer (index: number): node ({ index: number, isScrolling: boolean }): node
Collection.cellSizeAndPositionGetter (index: number): { height: number, width: number, x: number, y: number } ({ index: number }): { height: number, width: number, x: number, y: number }
FlexColumn.cellDataGetter (dataKey: string, rowData: any, columnData: any): any ({ columnData: any, dataKey: string, rowData: any }): any
FlexColumn.cellRenderer (cellData: any, dataKey: string, rowData: any, rowIndex: number, columnData: any): element ({ cellData: any, columnData: any, dataKey: string, isScrolling: boolean, rowData: any, rowIndex: number }): node
FlexTable.onHeaderClick (dataKey: string, columnData: any): void ({ dataKey: string, columnData: any }): void
FlexTable.onRowClick (rowIndex: number): void ({ index: number }): void
FlexTable.rowClassName (rowIndex: number): string ({ index: number }): string
FlexTable.rowGetter (index: int): any ({ index: int }): any
FlexTable.rowHeight (index: number): number ({ index: number }): number
FlexTable.sort (sortBy: string, sortDirection: SortDirection): void ({ sortBy: string, sortDirection: SortDirection }): void
Grid.columnWidth (index: number): number ({ index: number }): number
Grid.rowHeight (index: number): number ({ index: number }): number
InfiniteLoader.isRowLoaded (index: number): boolean ({ index: number }): boolean
VirtualScroll.rowHeight (index: number): number ({ index: number }): number
VirtualScroll.rowRenderer (index: number): node ({ index: number, isScrolling: boolean }): node

Backwards compatible changes

Cells are cached while scrolling

In the past, react-virtualized has not cached cells. This was done to avoid causing problems with cells that may change. If Grid renders a cached version- how will the changes be shown? However scrolling often causes the rapid creation of many cells. This is an unfortunate combination.

As of version 7, Grid (and HOCs built on top of it such as VirtualScroll and FlexTable) will cache cells while a user is scrolling. Once scrolling has completed (after a short debounce timer) the cache will be cleared and the currently-visible range of cells will be refreshed.

Cell renderers receive an isScrolling parameter

Related to the above change, cell renderers will now receive an additional parameter- isScrolling. This is a named parameter and so it can be ignored in many cases. However if a cell's contents are expensive to render, this parameter can enable conditional rendering of "lighter weight" content while a scroll is in progress.

Defer cell measurement until necessary

In version <= 6 of react-virtualized, the Grid component pre-measures and caches sizes for all columns and rows. We can avoid that by estimating cell sizes for portions of the Grid that have not yet been rendered. This change should enable more performant implementation of just-in-time calculated sizes (see below).

Support just-in-time calculated cell sizes

Create a new HOC (CellMeasurer) that's capable of measuring a cell's width (given a fixed height) or height (given a fixed width). This component can be used to support dynamic row heights for VirtualScroll lists or dynamic column widths / row heights within a Grid.

An example of how it is meant to be used is:

<CellMeasurer
  cellRenderer={cellRenderer}
  columnCount={columnCount}
  height={height}
  rowCount={rowCount}
>
  {({ getColumnWidth }) => (
    <Grid
      columnCount={columnCount}
      columnWidth={getColumnWidth}
      height={height}
      cellRenderer={cellRenderer}
      rowCount={rowCount}
      rowHeight={height}
      width={width}
    />
  )}
</CellMeasurer>

More flexible styling

All elements that could be styled via custom CSS class names will now also support custom inline styles.