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

Beta fix stub cells #460

Merged
merged 7 commits into from
Jun 25, 2019
Merged

Beta fix stub cells #460

merged 7 commits into from
Jun 25, 2019

Conversation

pradeepnschrodinger
Copy link
Collaborator

@pradeepnschrodinger pradeepnschrodinger commented Jun 5, 2019

(Side effect / regression from #454)

Description

Cells can have stale props.

Our buffered rows renders stub/fake rows to avoid mounts/unmounts. These rows have temporary props that don't reflect the table's props since the rows won't anyway be visible to the user. But the props propagate to the cell.
The cells have a shouldComponentDidUpdate to skip renders, so even when the rows become "real" the cells aren't re-rendered with the updated props.

Added an example to easily catch these cases in the future.

Motivation and Context

Fixes the issue seen in the screen shot. You'll see blank cells.

How Has This Been Tested?

Using auto scroll example

Screenshots (if appropriate):

FDT-Stale-Cells (1)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.

rowsCount={dataList.getSize()}
width={1000}
height={500}
scrollLeft={scrollLeft}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scrollLeft and scrollTop specified since we make use of controlled scrolling

height={500}
scrollLeft={scrollLeft}
scrollTop={scrollTop}
onVerticalScroll={this.onVerticalScroll}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are needed since the user can also scroll the table directly outside of our "autoscroll" logic

scrollTop: prevState.scrollTop + (prevState.verticalScrollDelta || 0),
scrollLeft: prevState.scrollLeft + (prevState.horizontalScrollDelta || 0),
}));
}, 16);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

60fps

justify-content: space-around;
align-items: baseline;
}
.autoScrollCell {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

center text both horizontally and vertically


.autoScrollContainer {
.autoScrollControls {
display: flex;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just space the controls evenly (both between and outside)

// if the row doesn't exist in the buffer, assign a fake row to it.
// this is so that we can get rid of unnecessary row mounts/unmounts
// render each row from the buffer into the static row array
for (let i = 0; i < this._staticRowArray.length; i++) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored so that there's only a single loop over the rows

this._staticRowArray[i] = this.getStubRow(i, true, -1);
}
continue;
rowIndex = this._staticRowArray[i] && this._staticRowArray[i].props.index;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we take the previous rendered row to avoid unmounts

if it is still undefined (aka, fake row), it will be rendered as null

let rowProps = {};

// if row exists, then calculate row specific props
if (!fake) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was were we had trouble (actual issue)

previously rows outside the viewport were seen as stub/fake, and hence given bad props

showScrollbarY={props.showScrollbarY}
visible={visible}
fake={fake}
{...rowProps}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apply the row specific props (will be an empty object for fake/stub rows)

Copy link
Member

@wcjordan wcjordan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Is there anyway to write a unit test which would have caught this?

@wcjordan
Copy link
Member

It might be worth having @mycrobe & @novakps look at this as well

@pradeepnschrodinger pradeepnschrodinger added bug regression issue that was "fixed" but got reopened later on labels Jun 13, 2019
@pradeepnschrodinger
Copy link
Collaborator Author

pradeepnschrodinger commented Jun 17, 2019

lgtm. Is there anyway to write a unit test which would have caught this?

Good idea. No idea if it's possible though, but I'll investigate...
Made an issue (#466) for tracking since I think we should write the test after we merge this PR (it's a important bug fix)

/>;
this._staticRowArray[i] = this.renderRow({
rowIndex,
key: i,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of interest, why is this the key not set to rowIndex?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because if the key is given as a function of rowIndex, rows will get mounted/unmounted whenever row indexes change. So we keep the keys constant, form 0 to no:rows present.

FDT uses IntegerBufferSet to manage row index to key mappings, so that when you scroll and it leads to a new row getting visible in the viewport, it'll replace the old one that went outside the viewport.

So basically if we scroll down by 1 row, for an initial viewport of 10 rows, then row 0 at key 0 might gets replaced by row 10, and the key should still be 0 to prevent react mounting/unmounting.

Copy link
Collaborator

@mycrobe mycrobe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@novakps novakps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@pradeepnschrodinger pradeepnschrodinger merged commit 5fc1b71 into v1.0-beta Jun 25, 2019
@alecf
Copy link

alecf commented Jun 29, 2019

This broke body scrolling + resizing for a project I'm working on (sadly, not open source) - I don't have a simplified test case but maybe symptoms can help flush this out:

basically happened is the body area stopped scrolling in any direction, while the header happily scrolled left and right. Resizing the container that the table was in was also not recognized - when our table is first rendered it has 3 rows, but when you drag it taller, only the original 3 rows stay on the screen.

We have our own custom cells which wrap the included Cells - i.e. they are stateless function components whose only child is the Cell imported here - they worked fine until 1.0.0-beta.21, and reverting back to 1.0.0-beta.20 fixed the problem for us. (we had to use our own wrappers because of something in a very old version, it may be that we can use the new cells... I will experiment and report back)

@pradeepnschrodinger
Copy link
Collaborator Author

@alecf , that's unfortunate to hear. Any updates here? I'm not seeing the issue mentioned...

@cmoad
Copy link

cmoad commented Aug 19, 2019

We are experiencing the same problem as @alecf. Scrolling stopped working completely at beta.21 and is still not working with beta.25. The virtual scroll bar moved up and down, the shadows appear and disappear at appropriate times, but the actual content inside the table doesn't move at all. Any recommendation on where to start with debugging this?

@pradeepnschrodinger
Copy link
Collaborator Author

Hey @cmoad, could you also specify these:

  • browser name
  • device used
  • whether touch scrolling is used
  • direction of scrolling and whether it is used through the scrollbar thumb
  • table props

A reproducible example will also really help in nailing the exact issue.

For debugging, you can check FixedDataTableCell, which is responsible for rendering your cell (also translates it). Maybe the shouldComponentUpdate method returns false for some reason?

Making up a new issue for this would be better, and we can continue the discussion over there.

This was referenced Sep 16, 2019
@pradeepnschrodinger
Copy link
Collaborator Author

@alecf and @cmoad, we released a fix for the scroll issue you guys had mentioned. Please use the latest beta v1.0.0-beta.28.

@pradeepnschrodinger pradeepnschrodinger deleted the beta-fix-stub-cells branch January 5, 2021 00:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug regression issue that was "fixed" but got reopened later on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants