0

VirtualScroll (List) コンポーネントをほぼ 1 日中チューニングしてきましたが、うまくいきません。

反応仮想化リストを使用してチャットメッセージを表示する Web ベースのチャットアプリケーションを構築しています。メッセージの内容と高さが異なる場合があるため、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 に答える