我在 StackOverflow 上浏览了很多答案。我也在这里浏览了 List 文档react-virtualized/List。但是,我仍然无法理解如何在反应虚拟化列表中动态设置行高。如何计算rowHeight
prop 函数中的高度?
我可以调用我的函数,如rowHeight={({ index }) => this.computeRowHeight({ index })}
. 但是该函数将如何计算行高?
以下是供参考的代码。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { AutoSizer, InfiniteLoader, List } from 'react-virtualized';
import _ from 'lodash';
class InfiniteList extends Component {
constructor(props) {
super(props);
this.state = {
list: props.list,
loading: false
};
}
componentDidMount() {
fetch('http://jsonplaceholder.typicode.com/comments')
.then((response) => {
response.json().then((data) => {
this.setState({
list: _.concat(this.state.list, _.map(data, 'body')),
loading: false
});
});
});
}
isRowLoaded({ index }) {
return !!this.state.list[index];
}
loadMoreRows({ startIndex, stopIndex }) {
if (this.state.loading) {
return;
}
this.setState({
loading: true
});
return fetch('http://jsonplaceholder.typicode.com/comments')
.then((response) => {
response.json().then((data) => {
// Simulate delay
setTimeout(() => {
this.setState({
list: _.concat(this.state.list, _.map(data, 'body')),
loading: false
});
}, 3000);
});
});
}
rowRenderer({ key, index, isScrolling, isVisible, style }) {
if (isVisible) {
return (
<div key={key}>
<div style={style}>#{this.state.list[index]}.</div>
</div>
);
}
}
render() {
return (
<div>
<InfiniteLoader
isRowLoaded={({ index }) => this.isRowLoaded({ index })}
loadMoreRows={({ startIndex, stopIndex }) => this.loadMoreRows({ startIndex, stopIndex })}
rowCount={this.state.list.length}
>
{({ onRowsRendered, registerChild }) => (
<AutoSizer disableHeight>
{({ width }) => (
<List
onRowsRendered={onRowsRendered}
ref={registerChild}
width={width}
height={320}
rowCount={this.state.list.length}
rowHeight={40}
rowRenderer={({ key, index, isScrolling, isVisible, style }) => this.rowRenderer({ key, index, isScrolling, isVisible, style })}
/>
)}
</AutoSizer>
)}
</InfiniteLoader>
{this.state.loading && <p>Loading...</p>}
</div>
);
}
}
const list = [];
ReactDOM.render(
<InfiniteList list={list} />,
document.querySelector('#root')
);
更新
动态高度现在与以下代码一起使用CellMeasurer
。但是,不幸this.loadMoreRows()
的是函数没有被调用InfiniteLoader
。没有CellMeasurer
它也不起作用。我不确定我在下面的代码中做错了什么。
import React, { Component } from 'react';
import { AutoSizer, CellMeasurer, InfiniteLoader, List } from 'react-virtualized';
import _ from 'lodash';
class InfiniteList extends Component {
constructor(props) {
super(props);
this.state = {
list: props.list,
loading: false
};
}
componentDidMount() {
fetch('http://jsonplaceholder.typicode.com/comments')
.then((response) => {
response.json().then((data) => {
this.setState({
list: _.concat(this.state.list, _.map(data, 'body')),
loading: false
});
});
});
}
isRowLoaded({ index }) {
return !!this.state.list[index];
}
loadMoreRows({ startIndex, stopIndex }) {
if (this.state.loading) {
return;
}
this.setState({
loading: true
});
return fetch('http://jsonplaceholder.typicode.com/comments')
.then((response) => {
response.json().then((data) => {
// Simulate delay
setTimeout(() => {
this.setState({
list: _.concat(this.state.list, _.map(data, 'body')),
loading: false
});
}, 3000);
});
});
}
rowRenderer({ key, index, isScrolling, isVisible, style }) {
if (isVisible) {
return (
<div key={key} style={style}>#{index} {this.state.list[index]}.</div>
);
}
}
cellRenderer({ columnIndex, key, rowIndex, style }) {
return (
<div
key={key}
style={style}
>
<div>#{rowIndex} {this.state.list[rowIndex]}.</div>
</div>
);
}
render() {
return (
<div>
<InfiniteLoader
isRowLoaded={isRowLoaded => this.isRowLoaded(isRowLoaded)}
loadMoreRows={loadMoreRows => this.loadMoreRows(loadMoreRows)}
rowCount={this.state.list.length}
>
{({ onRowsRendered, registerChild }) => (
<AutoSizer disableHeight>
{({ width }) => (
<CellMeasurer
cellRenderer={cellRenderer => this.cellRenderer(cellRenderer)}
columnCount={1}
rowCount={this.state.list.length}
>
{({ getRowHeight }) => (
<List
onRowsRendered={onRowsRendered}
ref={registerChild}
width={width}
height={400}
rowCount={this.state.list.length}
rowHeight={getRowHeight}
rowRenderer={rowRenderer => this.rowRenderer(rowRenderer)}
/>
)}
</CellMeasurer>
)}
</AutoSizer>
)}
</InfiniteLoader>
{this.state.loading && <p>Loading...</p>}
</div>
);
}
}
const list = [];
ReactDOM.render(
<InfiniteList list={list} />,
document.querySelector('#root')
);
任何帮助将不胜感激。谢谢!