useInfiniteScroll
useInfiniteScrollは、無限スクロール機能を提供するカスタムフックです。
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。使い方
import { useInfiniteScroll } from "@yamada-ui/react"
import { useInfiniteScroll } from "@/components/ui"
import { useInfiniteScroll } from "@workspace/ui"
const { ref, finish } = useInfiniteScroll()
ビューポートを指定する
ビューポートを指定する場合は、rootRefにrefを設定します。
rootRefが設定されない場合は、ブラウザのビューポートが使用されます。const rootRef = useRef<HTMLDivElement | null>(null)
const resetRef = useRef<() => void>(noop)
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
resetRef,
rootRef,
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack h="full" alignItems="flex-start">
<VStack
ref={rootRef}
borderWidth="1px"
overflowY="auto"
p="lg"
h="sm"
rounded="l2"
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
</VStack>
<Button onClick={() => resetRef.current()}>Reset</Button>
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。rootMarginを設定する
rootMarginを設定する場合は、rootMarginに文字列を設定します。
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
rootMargin: "300px 0px 0px 0px",
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。thresholdを設定する
thresholdを設定する場合は、thresholdに数値を設定します。
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
threshold: 1,
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。初回に読み込む
初回に読み込む場合は、initialLoadをtrueに設定します。デフォルトでは、initialLoadがfalseに設定されており、初回(index=0)のonLoadは実行されません。
true: スクロール量に関わらず、初回のonLoadは実行され、提供されるindexは0から始まります。
false: スクロールが一定に達するとonLoadが実行され、提供されるindexは1から始まります。
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
initialLoad: true,
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。開始するindexを変更する
開始するindexを変更する場合は、startIndexに数値を設定します。デフォルトは、1です。
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
startIndex: 3,
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。反転させる
反転させる場合は、reverseをtrueに設定します。デフォルトは、falseです。
const rootRef = useRef<HTMLDivElement>(null)
const [count, setCount] = useState<number>(50)
const { ref, finish } = useInfiniteScroll({
reverse: true,
rootRef,
onLoad: ({ finish, index }) => {
console.log("onLoad", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
},
})
return (
<VStack ref={rootRef} gap="md" h="full" overflow="auto">
{!finish ? (
<Center ref={ref} w="full">
<Loading.Oval fontSize="2xl" />
</Center>
) : null}
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</VStack>
)
こちらのコードを使用する場合は、
"use client"をファイルの上部に追加する必要があります。