react-virtualized icon indicating copy to clipboard operation
react-virtualized copied to clipboard

List row render to default height between cache.clear(i) and recomputeRowHeights(i), mess up scrollTop position

Open markni opened this issue 7 years ago • 12 comments

We are using List and CellMeasurer in our project, we noticed our list scroll up after cache.clear(10) is called. After logging everything, here is what happens:

Basic code:

cache.clear(10);
this.ref.recomputeRowHeights(10);

Logs:

  • Current List scrollTop: 18440
  • Current cached index 10 row height: 130
  • We notice item data has changed, So we run cache.clear(10)
  • Log shows cache.rowHeight() is running, because index 10 is cleared, it returns our default row - height: 90
  • The list height become shorter and re-rendering
  • recomputeRowHeights(10) is finally finished
  • recompute result shows new height is still 130, Current cached index 10 row height set to 130 again.
  • Log shows cache.rowHeight() is running again, The list height become taller and re-rendering
  • onScroll event on List is triggerd, current List scrollTop now auto changed to 18400, exactly the 40 difference between measured height(130) and default height(90).

Basically, cache.clear(index) causing the list item to re-render at default height. Then recomputeRowHeights(index) fixes the height but scrollTop is broken due to this.

I am not sure why recomputeRowHeights does not update cache directly. And wondering if there is correct way for handling this.

markni avatar Oct 20 '17 06:10 markni

Can you provide either a failing unit test or a repro that shows this happening? You can start by forking one of these:

  • Code Sandbox: https://codesandbox.io/s/03qpzq1p9p?module=%2FExample.js
  • Plnkr: https://plnkr.co/edit/6syKo8cx3RfoO96hXFT1

bvaughn avatar Oct 21 '17 16:10 bvaughn

@bvaughn Sure. Here is a simple plnkr example:

https://plnkr.co/edit/8r8VVEMMzqO9BEYLiXr8?p=preview

You should able to see scroll bar jump back after clear cache, despite the new measured row height not change at all.

markni avatar Oct 21 '17 23:10 markni

Cool. Thanks!

bvaughn avatar Oct 22 '17 00:10 bvaughn

I am seeing the same issue on my end. I’m inserting data above the current index, but after a proper lifecycle cache.clear() and list.recomputeRowHeights() scrollTop doesn’t recompute properly. It’s happening exactly the same way as being reported. I will also work on a Plinkr to show what’s happening. :)

noeljackson avatar Oct 24 '17 23:10 noeljackson

not sure if it's exactly the same issue, but this is happening for me except its with grids. I have 2 grids (header, body). When body column changes (length of data input changes) the body columns recalculate properly. Each odd update call recomputes the header grid size properly, but every even update call resets it to the default size. This causes a jumping effect in the size of the header grid.

Hakaze avatar Jan 05 '18 00:01 Hakaze

+1

Qwal avatar Feb 23 '18 11:02 Qwal

In my project I was able to solve this problem (or at least one very similar) by replacing the call to recomputeRowHeights() with a call to forceUpdateGrid(). I have yet to see any problems with this alternative approach, but whether it's the proper solution I don't know. The documentation states that forceUpdateGrid is useful when data has changed but heights have not, however I suspect (without looking into the source) that when rows have been cleared from the cache, re-rendering the grid also forces CellMeasurer to recompute the row heights, while bypassing the step where default heights are used.

imensha avatar Mar 07 '18 09:03 imensha

Any news on how to fix this? I'm running into the same issue.

jcarroll2007 avatar Mar 12 '18 12:03 jcarroll2007

For me it worked to use measure rather than recomputeRowHeights, as suggested here: https://stackoverflow.com/questions/47168920/resetting-row-heights-causes-incorrect-row-offset-to-get-calculated

jfulse avatar Nov 28 '18 19:11 jfulse

In my project I was able to solve this problem (or at least one very similar) by replacing the call to recomputeRowHeights() with a call to forceUpdateGrid(). I have yet to see any problems with this alternative approach, but whether it's the proper solution I don't know. The documentation states that forceUpdateGrid is useful when data has changed but heights have not, however I suspect (without looking into the source) that when rows have been cleared from the cache, re-rendering the grid also forces CellMeasurer to recompute the row heights, while bypassing the step where default heights are used.

That solution solved the issue for me! Thanks a lot!

lisandrolan avatar Feb 06 '19 22:02 lisandrolan

In my project I was able to solve this problem (or at least one very similar) by replacing the call to recomputeRowHeights() with a call to forceUpdateGrid(). I have yet to see any problems with this alternative approach, but whether it's the proper solution I don't know. The documentation states that forceUpdateGrid is useful when data has changed but heights have not, however I suspect (without looking into the source) that when rows have been cleared from the cache, re-rendering the grid also forces CellMeasurer to recompute the row heights, while bypassing the step where default heights are used.

This issue looks like still remaining. I was also able to fix it thanks to @imensha.

dyong0 avatar Oct 19 '20 11:10 dyong0

Faced a similar problem for Grid. I tried to selectively clear the cache and selectively recompute the grid. But in the end, my solution is to only call recomputeGridSize when I'm sure the size of the cells might have changed. Otherwise, just use forceUpdate.

dkskv avatar May 25 '22 12:05 dkskv