我已經經歷了很多StackOverflow的答案。我在這裏也經歷了List文檔,react-virtualized/List。但是,我仍然無法理解如何在react-virtualized列表中動態設置行高度。如何計算rowHeight
道具函數的高度?如何在react-virtualized List中設置動態行高?
我可以打電話給我的功能,如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')
);
任何幫助將不勝感激。謝謝!
添加到德魯的答案,如果你不知道任何關於你的內容的大小,你可能想要使用像CellMeasurer這樣的另一個react-virtualized組件。我也聽說過人們使用react-measure與react-virtualized結果很好。 – brianvaughn
@brianvaughn謝謝!以前我無法通過CellMeasurer獲得動態高度。但是,我再次嘗試了一下,現在它正在工作(儘管有時很少的行重疊)。但是,不幸的是我的'this.loadMoreRows()'函數沒有在InfiniteLoader中調用。我認爲它在CellMeasurer之前也沒有工作。所以它與CellMeasurer無關。我不確定我在這裏做錯了什麼。謝謝你的時間! – krishnaxv
我明白了這一點。我必須在'InfiniteLoader'中的'rowCount'中給出任意高數字,而不是'rowCount = {this.state.list.length}'。 – krishnaxv