0

我几乎一整天都在调整 VirtualScroll (List) 组件,但没有运气。

我正在构建一个基于 web 的聊天应用程序,其中使用 react-virtualized List 来显示聊天消息。由于消息可能有不同的内容和不同的高度,我使用react-measure计算项目高度并在 rowRenderer 中发出recomputeRowHeights 。

结果很糟糕,每当我停止滚动时,VirtuallScroll List 都会跳来跳去。例如,当我滚动到浏览器的一半时,我应该看到消息的中间,但它总是突然移动偏移量。请看一下录制的视频: https ://drive.google.com/file/d/0B_W64UoqloIkcm9oQ08xS09Zc1k/view?usp=sharing

由于我只使用 List 和 Autosizer 组件,所以我只将所需的 css 文件调整到我的项目中,就像 ```

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

```

对于 render 方法,我在 rowRender 中嵌套了很多 flex 组件: 下面是代码:

```

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'
    };

    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>
            );
        }
    }
}

```

我读了几个文档说 Flexbox 可能会拦截滚动事件,但即使我添加了overflow-y: hidden到嵌套组件,我也没有看到问题消失。你以前见过这种错误的 List 组件滚动行为吗?

欢迎任何建议。

4

1 回答 1

1

我看不到视频,但我想我最近有类似的事情。据我所知,您没有使用style传递给您的_rowRenderer方法的参数。此参数包含一些 CSS 转换,使行显示在滚动列表中的右侧垂直位置。

于 2016-11-29T21:42:06.393 回答