虚拟列表
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
const list = Array.from({ length: 20000 }, (v, k) => {
return {
i: k,
h: Math.ceil(20 * Math.random()) + 20,
};
});
class App extends Component {
listRow = [];
state = {
top: 0,
bottom: 0,
listRow: [],
list: list,
};
render() {
const offset = 600
const { listRow, top, bottom } = this.state;
return (
<div className="App">
<div
onScroll={(e) => {
const top = e.target.scrollTop;
let _top = 0
let _bottom = 0
const height = 400;
let allH = 0;
for (let index = 0; index < listRow.length; index++) {
const h = listRow[index].height;
allH = allH + h;
if (top < allH + offset && top + height > allH - offset) {
this.listRow[index].flag = false;
} else if (top >= allH + offset){
_top = _top + h
this.listRow[index].flag = true;
} else if (top + height <= allH - offset){
_bottom = _bottom + h
this.listRow[index].flag = true;
}
}
this.setState({
top: _top,
bottom: _bottom,
listRow: this.listRow,
});
}}
style={{ background: "red", height: 400, overflow: "auto" }}
>
<div style={{height: top}}></div>
{list.map((item, index) => {
const flag = listRow[index] ? listRow[index].flag : false;
if (!flag) {
return (
<div
ref={(e) => {
if (!this.listRow[index]) {
this.listRow[index] = {
height: item.h,
};
this.setState({
listRow: this.listRow,
});
}
}}
style={{
height: item.h,
justifyContent: "center",
background: flag ? "blue" : "yellow",
}}
key={index}
>
{item.i}
</div>
);
} else {
return null;
}
})}
<div style={{height: bottom}}></div>
</div>
{/* <p style={{ width: 400 }}>{JSON.stringify(listRow)}</p> */}
</div>
);
}
}
export default App;