欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React虛擬列表的實現代碼

 更新時間:2023年08月27日 09:22:24   作者:Kakarotto  
最近看了vueuse的useVirtualList的實現方式,發(fā)現虛擬滾動效果不錯,就嘗試著同樣的寫法改成react版本,虛擬列表主要包含三部分組成,offset,viewcapacity,overscan,本文就給大家介紹一下React虛擬列表的實現,需要的朋友可以參考下

最近看了vueuse的useVirtualList的實現方式,發(fā)現虛擬滾動效果不錯,就嘗試著同樣的寫法改成react版本。

虛擬列表主要包含三部分組成,示意圖如下:

定義一個 useVirtualList 的 hook 需要接收兩個參數,一是接收所有的數據,二是定義一些配置參數;需要返回的四個參數,一是當前加載的列表,二是獲取容器的 ref 和容器滾動事件,三是快速定位的方法,四是內層容器的樣式?;镜拇a結構如下:

export type UseVirtualListOptions = {
	// 如果是每條數據的高度相同為number 否則通過方法計算高度
	itemHeight: number | ((index: number) => number);
	overscan?: number;
};
export const useVirtualList = (
	list: AllItems[],
	options: UseVirtualListOptions
): UseVirtualListReturn => {
	const containerRef = useRef(null);
	const [currentList, setCurrentList] = useState<CurrentList[]>([]);
	const [wrapperStyle, setWrapperStyle] = useState({
		width: "100%",
		height: "0px",
		marginTop: "0px",
	});
	return {
		list: currentList,
		containerProps: {
			ref: containerRef,
			onScroll: () => {},
		},
		scrollTop,
		wrapperStyle,
	};
};

因為需要容器的高度和滾動距離來計算加載的內容,因此需要在 dom 掛載完成后執(zhí)行。

1、計算容器的的高度能顯示的數據

如果 itemHeight 類型為 number,則可以通過容器高度 / itemHeight 來計算容器能顯示多少條數據,否則需要把上一次開始索引作為起始值,預估滾動之后能夠在可視區(qū)域顯示多少數據。

const getViewCapacity = (containerHeight: number) => {
	if (typeof itemHeight === "number") {
		return Math.ceil(containerHeight / itemHeight);
	}
	let sum = 0;
	let capacity = 0;
	const { start = 0 } = state;
	console.log(start);
	for (let i = start; i < list.length; i++) {
		const height = itemHeight(i);
		sum += height;
		if (sum >= containerHeight) {
			capacity = i;
			break;
		}
	}
	return capacity - start;
};

2、計算滾動偏移的數據量

如果 itemHeight 類型為 number,則可以通過容器高度 / itemHeight 來計算滾動偏移的數據量,否則需要對滾動偏移的 dom 高度進行累加,計算出偏移的數據量。

const getOffset = (scrollTop: number) => {
	if (typeof itemHeight === "number") {
		return Math.floor(scrollTop / itemHeight) + 1;
	}
	let sum = 0;
	let offset = 0;
	for (let i = 0; i < list.length; i++) {
		const height = itemHeight(i);
		sum += height;
		if (sum >= scrollTop) {
			offset = i;
			break;
		}
	}
	return offset + 1;
};

3、計算滾動時需要加載的數據

需要加載的數據開始位置 = 滾動偏移量 - 預加載的數量
需要加載的數據結束位置 = 滾動偏移量 + 可視區(qū)域顯示數據量 + 預加載數據量
如果開始位置 < 0 則從 0 開始,結束位置大于總數組長度,則結束位置為總數據的長度

const from = offset - overscan;
const to = offset + viewCapacity + overscan;
state.start = from < 0 ? 0 : from;
state.end = to > list.length ? list.length : to;
setCurrentList(() => {
	return list.slice(state.start, state.end).map((ele, index) => ({
		data: ele,
		index: index + state.start,
	}));
});

4、計算列表容器的高度和滾動的高度

列表容器的高度 = 數據長度 * 預估每條數據的高度 - 滾動偏移的高度

因為加載的數據不是每次都從 0 開始,但每次渲染是從頂部開始的,所以滾動到高度大于數據的高度時,數據位于可視區(qū)域的上方,此時需要設置 marginTop,讓加載的數據顯示在可視區(qū)域的頂部,但如果總高度不變,數據全部加載完成后,底部會有大面積留白。

const computedWrapperStype = () => {
	const offsetTop = getDistanceTop(state.start);
	setWrapperStyle({
		width: "100%",
		height: `${totalHeight() - offsetTop}px`,
		marginTop: `${offsetTop}px`,
	});
};

5、添加快速定位功能

當在輸入框數據要定位的索引值時,可以根據索引值計算出可視區(qū)域上方需要偏移的高度,然后重新調用計算需要加載數據開始、結束位置的方法,即可實現快速定位。

const scrollTop = (index: number) => {
	if (containerRef.current) {
		(containerRef.current as HTMLDivElement).scrollTop = getDistanceTop(index);
		calculateRange();
	}
};

6、源碼地址

https://stackblitz.com/edit/vitejs-vite-oy7obm?file=src%2FApp.tsx

到此這篇關于React虛擬列表的實現代碼的文章就介紹到這了,更多相關React虛擬列表內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • react實現記錄拖動排序

    react實現記錄拖動排序

    這篇文章主要介紹了react實現記錄拖動排序的相關資料,需要的朋友可以參考下
    2023-07-07
  • React與Redux之數組處理講解

    React與Redux之數組處理講解

    這篇文章主要介紹了React與Redux之數組處理講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-09-09
  • 一文詳解手動實現Recoil狀態(tài)管理基本原理

    一文詳解手動實現Recoil狀態(tài)管理基本原理

    這篇文章主要為大家介紹了一文詳解手動實現Recoil狀態(tài)管理基本原理實例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • react清空ant.design中表單內容的方法實現

    react清空ant.design中表單內容的方法實現

    本文主要介紹了react清空ant.design中表單內容的方法實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-12-12
  • 解決antd的Table組件使用rowSelection屬性實現多選時遇到的bug

    解決antd的Table組件使用rowSelection屬性實現多選時遇到的bug

    這篇文章主要介紹了解決antd的Table組件使用rowSelection屬性實現多選時遇到的bug問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • React復制到剪貼板的示例代碼

    React復制到剪貼板的示例代碼

    本篇文章主要介紹了React復制到剪貼板的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 關于react ant 組件 Select下拉框 值回顯的問題

    關于react ant 組件 Select下拉框 值回顯的問題

    這篇文章主要介紹了關于react ant 組件 Select下拉框 值回顯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React如何通過@craco/craco代理接口

    React如何通過@craco/craco代理接口

    這篇文章主要介紹了React如何通過@craco/craco代理接口問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • useEffect中return函數的作用和執(zhí)行時機解讀

    useEffect中return函數的作用和執(zhí)行時機解讀

    這篇文章主要介紹了useEffect中return函數的作用和執(zhí)行時機,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • ReactNative實現的橫向滑動條效果

    ReactNative實現的橫向滑動條效果

    本文介紹了ReactNative實現的橫向滑動條效果,本文結合示例代碼給大家介紹的非常詳細,補充介紹了ReactNative基于寬度變化實現的動畫效果,感興趣的朋友跟隨小編一起看看吧
    2024-02-02

最新評論