question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

VirtualScroll (List) with dynamic item height scrolling not smooth and jumping

See original GitHub issue

I have been tuning the VirtualScroll (List) component for almost whole day but no luck. I’m building a web based chatting application in which uses the react-virtualized List to display the chatting messages. Since message may have different content and different height, I use react-measure to calculate the item height and issue the recomputeRowHeights in rowRenderer.

The result is bad, VirtuallScroll List will jump around whenever I stopped the scrolling. For example, when I scrolled to the half of browser, I should see the middle of the messages, but it always suddenly shift the offset. Please take a look at the recorded video: https://drive.google.com/file/d/0B_W64UoqloIkcm9oQ08xS09Zc1k/view?usp=sharing

Since I only use the List and Autosizer component, I only adapt the required css file into my project which is like

.VirtualScroll {
    width: 100%;
    outline: none;
}

For the render method, I nested a lot of flex components inside the rowRender: Here is the code:

    render() {
        const inChat = this.context.store.getState().inChat;
        const {conversationList} = this.state;
        const imgUrl = 'img/builtin-wallpaper-1.jpg';
        const backgroundStyle = {
            backgroundImage: 'url(' + imgUrl + ')',
            backgroundRepeat: 'no-repeat',
            backgroundSize: 'cover',
            backgroundPosition: 'top left'
        };

        // console.log('inChat');
        // console.log(inChat);

        if (inChat.id === this.id && inChat.status === 'FETCHING'){
            return (
                <Box column center height="80%">
                    <CircularProgress />
                </Box>
            );
        } else if (inChat.id === this.id && inChat.status === 'FETCHED'){
            return (
                <Box column flex="1 0 100%" style={backgroundStyle}>
                    <HorizontalToolBar/>
                    <AutoSizer disableHeight={true}>
                        {({ width }) => (
                            <List
                                ref={(element) => {this.VirtualScroll = element;}}
                                className='VirtualScroll'
                                height={window.innerHeight - toolbarHeight - textAreaHeight}
                                overscanRowCount={10}
                                noRowsRenderer={this._noRowsRenderer.bind(this)}
                                rowCount={conversationList.length}
                                rowHeight={i => {
                                    return (Measured_Heights[i.index] | 20);  // default Height = 58
                                }}
                                rowRenderer={this._rowRenderer}
                                scrollToIndex={undefined} // scroll to latest item
                                width={width}
                            />
                        )}
                    </AutoSizer>
                    <InputControl chatId={this.id} sendChatText={this._sendChatText.bind(this)}/>
                </Box>
            );
        } else {
            return null;
        }
    }

    _rowRenderer ({ index, key, style, isScrolling }) {
        console.log(Measured_Heights);

        const rowData = this._getDatum(index);
        // let renderItem;

        // console.log('index = ' + index + ' key = ' + key);

        if (rowData.type == 'conversation') {

            if (rowData.data.type == netModule.TYPE_SYSTEM) {
                // system message
                return (
                    <Measure key={key} onMeasure={(dims) => this._onMeasure(index, dims)}>
                        <SystemMessage data={rowData.data}/>
                    </Measure>
                )
            }

            if (rowData.data.senderId == this.state.selfProfile.username) {
                // outgoing message
                return (
                    <Measure key={key} onMeasure={(dims) => this._onMeasure(index, dims)}>
                        <RightMessage
                            screenWidth={(window.innerWidth - leftToolBarWidth) / 2 }
                            screenHeight={window.innerHeight - toolbarHeight}
                            data={rowData.data}/>
                    </Measure>
                );

            } else {
                // incoming message
                // append userProfile to left messages
                return (
                    <Measure key={key} onMeasure={(dims) => this._onMeasure(index, dims)}>
                        <LeftMessage
                            userId={rowData.data.senderId}
                            userProfile={this.state.groupUserProfiles[rowData.data.senderId]}
                            screenWidth={(window.innerWidth - leftToolBarWidth) / 2 }
                            screenHeight={window.innerHeight - toolbarHeight}
                            data={rowData.data}/>
                    </Measure>
                );
            }
        }
    }

I read a couple docs that Flexbox may be intercept the scrolling event, but even though I added overflow-y: hidden to nested component I didn’t see the issue disappear. Have you ever seen this wrong scrolling behavior with List component before? Any suggestion is welcome.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:19 (12 by maintainers)

github_iconTop GitHub Comments

18reactions
bhjcommented, Oct 7, 2016

@EllisShen I had a similar symptom when upgrading a VirtualScroll to List (8.x). Make sure you pass the style property in _rowRenderer() to the parent components it returns (and that the components render() the style)

2reactions
bvaughncommented, Oct 11, 2016

Docs are hard 😅 The more I write, the harder it is to find any given one.

I try to provide a simplified use-case/example with each component that shows its most basic functionality. In the case of List the example would be here. I think the rowRenderer in that example fills the role you’re describing?

Either way~ I happily welcome contributions to make the docs more user-friendly. I’ve been working with this library so long that I sometimes lose touch with common questions for people just starting out with it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

VirtualScroll (List) with dynamic item height scrolling not ...
I'm building a web based chatting application in which uses the react-virtualized List to display the chatting messages. Since message may have ...
Read more >
Build your Own Virtual Scroll - Part I - DEV Community ‍ ‍
We will start by building a simple one where the height is fixed for every row, and then discuss what to do when...
Read more >
Scrollspy · Bootstrap v5.0
Automatically update Bootstrap navigation or list group components based on scroll position to indicate which link is currently active in the viewport.
Read more >
ion-virtual-scroll - Ionic Framework
In order for virtual scroll to efficiently size and locate every item, it's very important every element within each virtual item does not...
Read more >
overscroll-behavior - CSS: Cascading Style Sheets | MDN
Default scroll overflow behavior is observed inside the element this value is set on (e.g. "bounce" effects or refreshes), but no scroll ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found