requestIdleCallback
2023年03月16日
一、Circle 组件实现
import React, { useMemo } from "react";
function getColor() {
const r = Math.floor(Math.random() * 255);
const g = Math.floor(Math.random() * 255);
const b = Math.floor(Math.random() * 255);
return `rgba(${r},${g},${b},0.8)`;
}
function getPosition(position) {
const { width, height } = position;
return {
left: Math.ceil(Math.random() * width) + "px",
top: Math.ceil(Math.random() * height) + "px",
};
}
function Circle(props) {
const { position } = props;
const style = useMemo(() => {
return {
width: "10px",
height: "10px",
position: "absolute",
background: getColor(),
...getPosition(position),
};
});
return <div style={style} className="circle"></div>;
}
export default Circle;
二、App.tsx 组件实现
import React, { useState, useRef, useEffect, Fragment } from "react";
import ReactDOM from "react-dom";
import Circle from "./circle";
function App() {
const container = useRef(null);
const [dataList, setDataList] = useState([]);
const [renderList, setRenderList] = useState([]);
const [eachRenderNum, setEachRenderNum] = useState(500);
const [position, setPosition] = useState({ width: 0, height: 0 });
const renderNewList = (index) => {
const list = dataList.slice(
(index - 1) * eachRenderNum,
index * eachRenderNum
);
return (
<Fragment key={index}>
{list.map((item, index) => (
<Circle key={index} position={position} />
))}
</Fragment>
);
};
const toRenderList = (index, times) => {
if (index > times) {
return;
}
setRenderList(renderNewList(index));
requestIdleCallback(() => {
toRenderList(++index, times);
});
};
useEffect(() => {
const { offsetHeight, offsetWidth } = container.current;
const originList = new Array(20000).fill(1);
setPosition({ width: offsetWidth, height: offsetHeight });
setDataList(originList);
}, []);
useEffect(() => {
let index = 1;
const times = Math.ceil(dataList.length / eachRenderNum);
toRenderList(index, times);
}, [dataList]);
return (
<div
style={{ width: "500px", height: "500px", position: "relative" }}
ref={container}
>
{renderList}
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));