From 7536a30a094d05b5b47ca9040c0bfa0fd94f85a3 Mon Sep 17 00:00:00 2001 From: luoyz Date: Tue, 24 Jan 2023 11:24:09 +0800 Subject: [PATCH] fix(useVirtualList): mutate style in react context --- packages/hooks/src/useVirtualList/index.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/hooks/src/useVirtualList/index.ts b/packages/hooks/src/useVirtualList/index.ts index 7bb55318a8..444af3500f 100644 --- a/packages/hooks/src/useVirtualList/index.ts +++ b/packages/hooks/src/useVirtualList/index.ts @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState, useRef } from 'react'; +import { useEffect, useMemo, useState, useRef, CSSProperties } from 'react'; import useEventListener from '../useEventListener'; import useLatest from '../useLatest'; import useMemoizedFn from '../useMemoizedFn'; @@ -6,6 +6,7 @@ import useSize from '../useSize'; import { getTargetElement } from '../utils/domTarget'; import type { BasicTarget } from '../utils/domTarget'; import { isNumber } from '../utils'; +import useUpdateEffect from '../useUpdateEffect'; type ItemHeight = (index: number, data: T) => number; @@ -27,6 +28,8 @@ const useVirtualList = (list: T[], options: Options) => { const [targetList, setTargetList] = useState<{ index: number; data: T }[]>([]); + const [wrapperStyle, setWrapperStyle] = useState({}); + const getVisibleCount = (containerHeight: number, fromIndex: number) => { if (isNumber(itemHeightRef.current)) { return Math.ceil(containerHeight / itemHeightRef.current); @@ -86,9 +89,8 @@ const useVirtualList = (list: T[], options: Options) => { const calculateRange = () => { const container = getTargetElement(containerTarget); - const wrapper = getTargetElement(wrapperTarget) as HTMLElement; - if (container && wrapper) { + if (container) { const { scrollTop, clientHeight } = container; const offset = getOffset(scrollTop); @@ -99,8 +101,10 @@ const useVirtualList = (list: T[], options: Options) => { const offsetTop = getDistanceTop(start); - wrapper.style.height = totalHeight - offsetTop + 'px'; - wrapper.style.marginTop = offsetTop + 'px'; + setWrapperStyle({ + height: totalHeight - offsetTop + 'px', + marginTop: offsetTop + 'px', + }); setTargetList( list.slice(start, end).map((ele, index) => ({ @@ -111,6 +115,13 @@ const useVirtualList = (list: T[], options: Options) => { } }; + useUpdateEffect(() => { + const wrapper = getTargetElement(wrapperTarget) as HTMLElement; + if (wrapper) { + Object.keys(wrapperStyle).forEach((key) => (wrapper.style[key] = wrapperStyle[key])); + } + }, [wrapperStyle]); + useEffect(() => { if (!size?.width || !size?.height) { return;