Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Episode 9.0 (The One About React Fiber) #577

Merged
merged 32 commits into from
Feb 17, 2017
Merged

Episode 9.0 (The One About React Fiber) #577

merged 32 commits into from
Feb 17, 2017

Conversation

bvaughn
Copy link
Owner

@bvaughn bvaughn commented Feb 13, 2017

To test version 9 yourself- npm i react-virtualized@next

You can also give it a spin on the demo site which is now powered by React fiber too!

Remaining TODO items

  • CellMeasurerCache should cache and return an average cell size as a sub for an unknown cell's width/height (instead of minWidth/minHeight). This will make it more accurate over time when estimating layout of previously unmeasured cells. (deferred)
  • Add a few remaining unit tests for new functionality
  • Update docs and write a better upgrade guide

Non-breaking changes

The following backwards-compatible issues will be addressed with version 9:

Bug fixes:

New features:

DEV mode warnings:

  • Use of CellMeasurer with an improperly configured Grid will now log a warning.
  • Grid cells rendered without a style prop now log a warning.

Backwards-breaking changes

  • Supported React versions have changed. Previously all React 14 and 15 releases were supported. Going forward only React 15.3 and newer will be supported. This was done to drop a peer dependency on react-addons-shallow-compare and replace it with React.PureComponent as the docs suggest.

screen shot 2017-02-13 at 1 44 43 pm

  • CellManager has been completely rewritten to support fiber. It's more flexible than before but uses a very different syntax. See below for more detailed instructions on how to upgrade.

CellMeasurer changes

Previously, CellMeasurer wrapped a Grid and measured all rows and/or columns, like so:

<CellMeasurer
  cellRenderer={cellRenderer}
  cellSizeCache={cellSizeCache}
  columnCount={columnCount}
  rowCount={rowCount}
>
  {({ getColumnWidth, getRowHeight }) => (
    <Grid
      columnCount={columnCount}
      columnWidth={getColumnWidth}
      cellRenderer={cellRenderer}
      rowCount={rowCount}
      rowHeight={getRowHeight}
      {...otherProps}
    />
  )}
</CellMeasurer>

This had one major drawback: CellMeasurer could not be used to measure only specific rows/columns. A secondary, related drawback was that cell measurements were cached by index. Because of this insertions, deletions, and re-ordering invalidated measurements and require re-measuring.

The new CellMeasurer wraps individual cells, allowing selective measurement. By providing a keyMapper, measurements can also be cached by cell ID instead of index- making them reusable after insertions, deletions, and re-orders. The new syntax for using CellMeasurer is like so:

// In this example, average cell width is assumed to be about 100px.
// This value will be used for the initial `Grid` layout.
// Cell measurements smaller than 75px should also be rounded up.
// Height is not dynamic.
const cache = new CellMeasurerCache({
  defaultWidth: 100,
  minWidth: 75,
  fixedHeight: true
});

function cellRenderer ({ columnIndex, key, parent, rowIndex, style }) {
  const content // Derive this from your data somehow

  return (
    <CellMeasurer
      cache={cache}
      columnIndex={columnIndex}
      key={key}
      parent={parent}
      rowIndex={rowIndex}
    >
      {content}
    </CellMeasurer>
  );
}

function renderGrid (props) {
  return (
    <Grid
      {...props}
      columnWidth={cache.columnWidth}
      deferredMeasurementCache={cache}
      cellRenderer={cellRenderer}
    />
  );
}

@bvaughn
Copy link
Owner Author

bvaughn commented Feb 16, 2017

D'oh! Sorry @edulan I missed your comment. Thank you!

I plan a final release soon- but until then you can play with it via npm i react-virtualized@next if you'd like to give it a spin early. I don't expect the API to change any. I'm mostly finishing up documentation and adding a few more automated tests.

@romulof
Copy link
Contributor

romulof commented Feb 21, 2017

Isn't Fiber only being enabled by default in React 16?
If so, the new CellMeasurer would require React 16 as dependency.

@bvaughn
Copy link
Owner Author

bvaughn commented Feb 21, 2017

CellMeasurer doesn't require React 16 to work. React 16 won't work with react-virtualized <= 8 though because the subtree/portal render method CellMeasurer used to use- which used to be synchronous- is asynchronous in React 16. So I rewrote CellMeasurer to support async out of the box and it is now compatible with React 16 (and older).

I did bump the React peer dependency up to 15.3 though because I wanted to use PureComponent and stop requiring people to also instead react-addons-shallow-compare for the shallowCompare util. Otherwise I would have been compat with 14, 15, and 16.

@romulof
Copy link
Contributor

romulof commented Feb 21, 2017

Great. I thought you were using some Fiber-specific feature.

I still need to invalidate/update cache if a cell changes size or this new CellMeasurer handles it automatically?

@bvaughn
Copy link
Owner Author

bvaughn commented Feb 21, 2017

Still need to manually invalidate. Otherwise I'd have to force layout frequently which would defeat the purpose.

@romulof
Copy link
Contributor

romulof commented Feb 22, 2017

Using this new CellMeasurer still renders the cell twice (for measure and actual rendering) ?

@bvaughn
Copy link
Owner Author

bvaughn commented Feb 22, 2017

Yes. You could prevent the second render (if it's worth it) using shouldComponentUpdate. The only prop that should change is the incoming style (which will have actual instead of estimated measurements).

@mquan
Copy link

mquan commented Feb 23, 2017

@bvaughn Is the way to manually trigger cell re-measurement here still valid? If not, can you point me to documentation of the new way of doing it for CellMeasurer & Grid combo? thanks

@bvaughn
Copy link
Owner Author

bvaughn commented Feb 23, 2017

@mquan The way to clear measurements now is to reset your CellMeasurerCache:

// Clear measurements so CellMeasurer will know to re-measure when it is next rendered
cellMeasurerCache.clearAll()

// Let Grid know to clear its cached position data and re-render
gridRef.recomputeGridSize()

@kirtimukha
Copy link

kirtimukha commented Sep 30, 2022

Maybe it's very simple question, but please understand I'm very new on react.
Can you let me know where do I put the cellMeasureCache.clearAll() function?
I'm having a proble lists are disappear when I scrolled up.
I used "cache.clear()" on " isRowLoaded (){ here:where i put the cache.clear() }"function now.

and this is my retunrn

[AutoSizer >
{({ width, height }) => (

{({ onRwsRendered, registerChild }) => (
[List
height={height}
autoHeight
width={width}
overscanRowCount={0}
rowCount={this.state.community_list.length}
rowHeight={this.cellMeasurerCache.rowHeight}
rowRenderer={this.renderRow.bind(this)}
onRowsRendered={onRwsRendered}
deferredMeasurementCache={this.cellMeasurerCache}
onScroll={this.scrollListener}
ref={registerChild}
className="ReactVirtualize_customClass"
/>
)}

)}

</>



Can you help me, please?  T.T

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants