diff --git a/src/hooks/useScrollTo.tsx b/src/hooks/useScrollTo.tsx index ce143c9..592a670 100644 --- a/src/hooks/useScrollTo.tsx +++ b/src/hooks/useScrollTo.tsx @@ -64,6 +64,7 @@ export default function useScrollTo( const [syncState, setSyncState] = React.useState<{ times: number; index: number; + key?: React.Key; offset: ScrollOffset; originAlign: ScrollAlign; targetAlign?: 'top' | 'bottom'; @@ -81,7 +82,11 @@ export default function useScrollTo( collectHeight(); - const { targetAlign, originAlign, index, offset: rawOffset } = syncState; + const { targetAlign, originAlign, offset: rawOffset } = syncState; + const index = + syncState.index >= 0 + ? syncState.index + : data.findIndex((item) => getKey(item) === syncState.key); const mergedAlign = targetAlign || originAlign; const offset = getOffset(rawOffset, { getSize, align: mergedAlign }); @@ -91,7 +96,7 @@ export default function useScrollTo( let targetTop: number | null = null; // Go to next frame if height not exist - if (height) { + if (height && index >= 0) { // Get top & bottom let stackTop = 0; let itemTop = 0; @@ -157,12 +162,13 @@ export default function useScrollTo( // Trigger next effect if (needCollectHeight) { - setSyncState({ - ...syncState, - times: syncState.times + 1, + setSyncState((prev) => ({ + ...prev, + times: prev.times + 1, + index, targetAlign: newTargetAlign, lastTop: targetTop, - }); + })); } } else if (process.env.NODE_ENV !== 'production' && syncState?.times === MAX_TIMES) { warning( @@ -187,12 +193,14 @@ export default function useScrollTo( syncScrollTop(arg); } else if (arg && typeof arg === 'object') { let index: number; + let key: React.Key; const { align } = arg; if ('index' in arg) { ({ index } = arg); } else { - index = data.findIndex((item) => getKey(item) === arg.key); + key = arg.key; + index = data.findIndex((item) => getKey(item) === key); } const { offset: rawOffset = 0 } = arg; @@ -200,6 +208,7 @@ export default function useScrollTo( setSyncState({ times: 0, index, + key, offset: rawOffset, originAlign: align, }); diff --git a/tests/scroll.test.js b/tests/scroll.test.js index f9dd1d2..0c1ea28 100644 --- a/tests/scroll.test.js +++ b/tests/scroll.test.js @@ -208,6 +208,31 @@ describe('List.Scroll', () => { expect(container.querySelector('ul').scrollTop).toEqual(520); }); + it('refreshes key index when data changes', () => { + const ref = React.createRef(); + + function Demo() { + const [data, setData] = React.useState(genData(1)); + + return ( + <> +