Skip to content

Commit 3dc2d83

Browse files
authored
fix(useInfiniteScroll): make canLoadMore reactive (#5110)
1 parent 5ebfedc commit 3dc2d83

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

packages/core/useInfiniteScroll/index.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,74 @@ describe('useInfiniteScroll', () => {
5656
expect(mockHandler).toHaveBeenCalledTimes(1)
5757
})
5858

59+
it('should not call loadMore when canLoadMore returns false', async () => {
60+
const mockHandler = vi.fn()
61+
const mockElement = givenMockElement()
62+
givenElementVisibilityRefMock(true)
63+
64+
useInfiniteScroll(mockElement, mockHandler, {
65+
canLoadMore: () => false,
66+
})
67+
68+
expect(mockHandler).not.toHaveBeenCalled()
69+
})
70+
71+
it('should call loadMore when canLoadMore returns true', async () => {
72+
const mockHandler = vi.fn()
73+
const mockElement = givenMockElement()
74+
givenElementVisibilityRefMock(true)
75+
76+
useInfiniteScroll(mockElement, mockHandler, {
77+
canLoadMore: () => true,
78+
})
79+
80+
expect(mockHandler).toHaveBeenCalledTimes(1)
81+
})
82+
83+
it('should stop calling loadMore when canLoadMore changes from true to false', async () => {
84+
const mockHandler = vi.fn()
85+
const mockElement = givenMockElement()
86+
givenElementVisibilityRefMock(true)
87+
88+
const canLoad = deepRef(true)
89+
const canLoadMoreSpy = vi.fn(() => canLoad.value)
90+
useInfiniteScroll(mockElement, mockHandler, {
91+
canLoadMore: canLoadMoreSpy,
92+
})
93+
94+
await flushPromises()
95+
expect(mockHandler).toHaveBeenCalledTimes(1)
96+
97+
canLoad.value = false
98+
99+
mockElement.dispatchEvent(new Event('scroll'))
100+
await flushPromises()
101+
102+
expect(mockHandler).toHaveBeenCalledTimes(1)
103+
})
104+
105+
it('should call loadMore when canLoadMore changes from false to true', async () => {
106+
const mockHandler = vi.fn()
107+
const mockElement = givenMockElement()
108+
givenElementVisibilityRefMock(true)
109+
110+
const canLoad = deepRef(false)
111+
const canLoadMoreSpy = vi.fn(() => canLoad.value)
112+
useInfiniteScroll(mockElement, mockHandler, {
113+
canLoadMore: canLoadMoreSpy,
114+
})
115+
116+
await flushPromises()
117+
expect(mockHandler).not.toHaveBeenCalled()
118+
119+
canLoad.value = true
120+
121+
mockElement.dispatchEvent(new Event('scroll'))
122+
await flushPromises()
123+
124+
expect(mockHandler).toHaveBeenCalledTimes(1)
125+
})
126+
59127
function givenMockElement({
60128
scrollHeight = 0,
61129
} = {}): HTMLDivElement {

packages/core/useInfiniteScroll/index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,16 @@ export function useInfiniteScroll<T extends InfiniteScrollElement>(
7676

7777
const isElementVisible = useElementVisibility(observedElement)
7878

79+
const canLoad = computed(() => {
80+
if (!observedElement.value)
81+
return false
82+
return canLoadMore(observedElement.value as T)
83+
})
84+
7985
function checkAndLoad() {
8086
state.measure()
8187

82-
if (!observedElement.value || !isElementVisible.value || !canLoadMore(observedElement.value as T))
88+
if (!observedElement.value || !isElementVisible.value || !canLoad.value)
8389
return
8490

8591
const { scrollHeight, clientHeight, scrollWidth, clientWidth } = observedElement.value as HTMLElement
@@ -102,7 +108,7 @@ export function useInfiniteScroll<T extends InfiniteScrollElement>(
102108
}
103109

104110
const stop = watch(
105-
() => [state.arrivedState[direction], isElementVisible.value],
111+
() => [state.arrivedState[direction], isElementVisible.value, canLoad.value],
106112
checkAndLoad,
107113
{ immediate: true },
108114
)

0 commit comments

Comments
 (0)