Skip to content

Commit

Permalink
fix(useInfiniteScroll): fix onScroll event not being triggered when…
Browse files Browse the repository at this point in the history
… target scroll
  • Loading branch information
vikiboss committed Jul 2, 2024
1 parent 00207f9 commit 73a9c98
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 19 deletions.
10 changes: 7 additions & 3 deletions src/use-infinite-scroll/demo.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Card, KeyValue, Zone, wait as mockFetch } from '@/components'
import { generateLoremIpsum, useInfiniteScroll, useSafeState } from '@shined/react-use'
import { useRef } from 'react'

export function App() {
const ref = useRef<HTMLDivElement>(null)
const [list, setList] = useSafeState<{ idx: number; text: string }[]>([])

const fetchData = async () => {
Expand All @@ -17,8 +19,10 @@ export function App() {
return newData
}

const scroll = useInfiniteScroll('#el-infinite-scroll', fetchData, {
canLoadMore: (pre) => (!pre ? true : pre[pre.length - 1].idx <= 100),
const scroll = useInfiniteScroll(ref, fetchData, {
canLoadMore: (pre) => {
return pre ? pre[pre.length - 1].idx <= 100 : true
},
})

return (
Expand All @@ -27,7 +31,7 @@ export function App() {
<KeyValue label="isLoading" value={scroll.isLoading} />
<KeyValue label="isLoadDone" value={scroll.isLoadDone} />
</Zone>
<div id="el-infinite-scroll" className="w-full h-80 bg-#666666/20 rounded overflow-scroll p-4">
<div ref={ref} className="w-full h-80 bg-#666666/20 rounded overflow-scroll p-4">
{list.map((item) => (
<div key={item.idx} className="my-2 p-2 bg-primary/40 dark:text-white rounded">
{item.text}
Expand Down
8 changes: 5 additions & 3 deletions src/use-infinite-scroll/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ import { Tip } from '@/components'

import Link from '@docusaurus/Link'

`UseScrollOptions` is options of `useScroll`, see [useScroll#options](/reference/use-scroll/#options) for more details.

```tsx
export type UseInfiniteScrollOptions<T extends HTMLElement = HTMLElement> = UseScrollOptions & {
export type UseInfiniteScrollOptions<T extends HTMLElement = HTMLElement> = {
/**
* scroll event callback
*/
onScroll?: (event: Event) => void
/**
* distance from the bottom of the scroll container
*
Expand Down
26 changes: 19 additions & 7 deletions src/use-infinite-scroll/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import { useRafState } from '../use-raf-state'
import { useStableFn } from '../use-stable-fn'
import { useTargetElement } from '../use-target-element'

import type { UseScrollOptions } from '../use-scroll'
import type { ElementTarget } from '../use-target-element'

export interface UseInfiniteScrollOptions<R> extends UseScrollOptions {
export interface UseInfiniteScrollOptions<R> {
/**
* scroll event callback
*/
onScroll?: (event: Event) => void
/**
* Whether to trigger the first load immediately
*
Expand Down Expand Up @@ -52,7 +55,7 @@ export interface UseInfiniteScrollReturns {
/**
* calculate the current scroll position to determine whether to load more
*/
calculate(): void
calculate(event: Event): void
}

/**
Expand All @@ -64,15 +67,24 @@ export function useInfiniteScroll<R = any, T extends HTMLElement = HTMLElement>(
onLoadMore: (previousReturn: R | undefined) => R | Promise<R>,
options: UseInfiniteScrollOptions<R> = {},
): UseInfiniteScrollReturns {
const { direction = 'bottom', immediate = true, interval = 100, canLoadMore = () => true, distance = 100 } = options
const {
immediate = true,
distance = 100,
direction = 'bottom',
interval = 100,
canLoadMore = () => true,
onScroll,
} = options

const el = useTargetElement<T>(target)
const previousReturn = useRef<R | undefined>(undefined)
const [state, setState] = useRafState({ isLoading: false, isLoadDone: false }, { deep: true })
const latest = useLatest({ state, direction, onLoadMore, interval })
const latest = useLatest({ state, direction, onScroll, onLoadMore, interval })

const calculate = useStableFn(async (event: Event) => {
const { state, direction, onLoadMore, interval, onScroll } = latest.current

const calculate = useStableFn(async () => {
const { state, direction, onLoadMore, interval } = latest.current
onScroll?.(event)

if (!canLoadMore(previousReturn.current)) {
return setState({ ...state, isLoadDone: true })
Expand Down
8 changes: 5 additions & 3 deletions src/use-infinite-scroll/index_zh-cn.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ import { Tip } from '@/components'

import Link from '@docusaurus/Link'

`UseScrollOptions` is options of `useScroll`, see [useScroll#options](/reference/use-scroll/#options) for more details.

```tsx
export type UseInfiniteScrollOptions<T extends HTMLElement = HTMLElement> = UseScrollOptions & {
export type UseInfiniteScrollOptions<T extends HTMLElement = HTMLElement> = {
/**
* scroll event callback
*/
onScroll?: (event: Event) => void
/**
* distance from the bottom of the scroll container
*
Expand Down
2 changes: 1 addition & 1 deletion src/use-scroll/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface UseScrollOptions {
*/
behavior?: ScrollBehavior
/**
*
* Whether to trigger the first load immediately
*/
immediate?: boolean
}
Expand Down
2 changes: 1 addition & 1 deletion src/use-scroll/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export interface UseScrollOptions {
*/
behavior?: ScrollBehavior
/**
*
* Whether to trigger the first load immediately
*/
immediate?: boolean
}
Expand Down
2 changes: 1 addition & 1 deletion src/use-scroll/index_zh-cn.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface UseScrollOptions {
*/
behavior?: ScrollBehavior
/**
*
* Whether to trigger the first load immediately
*/
immediate?: boolean
}
Expand Down

0 comments on commit 73a9c98

Please sign in to comment.