useInfiniteScroll
useInfiniteScroll
は、無限スクロール機能を提供するカスタムフックです。
インポート
import { useInfiniteScroll } from "@yamada-ui/react"
使い方
編集可能な例
const [count, setCount] = useState<number>(50) const { ref, isFinish } = useInfiniteScroll({ onLoad: ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, }) return ( <VStack> {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} </VStack> )
ビューポートを指定する
ビューポートを指定する場合は、rootRef
にref
を設定します。
rootRef
が設定されない場合は、ブラウザのビューポートが使用されます。
編集可能な例
const rootRef = useRef<HTMLDivElement>(null) const resetRef = useRef<() => void>(() => {}) const [count, setCount] = useState<number>(50) const { ref, isFinish } = useInfiniteScroll({ onLoad: ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, rootRef, resetRef, }) return ( <VStack alignItems="flex-start" h="full"> <Container ref={rootRef} flex="1" borderWidth="1px" rounded="md" p="md" overflowY="auto" > {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} </Container> <Button onClick={() => resetRef.current()}>Reset</Button> </VStack> )
rootMargin
を設定する
rootMarginを設定する場合は、rootMargin
に文字列を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) const { ref, isFinish } = useInfiniteScroll({ onLoad: ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, rootMargin: "300px 0px 0px 0px", }) return ( <VStack> {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} </VStack> )
threshold
を設定する
thresholdを設定する場合は、threshold
に数値を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) const { ref, isFinish } = useInfiniteScroll({ onLoad: ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, threshold: 1, }) return ( <VStack> {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} </VStack> )
初回に読み込む
初回に読み込む場合は、initialLoad
をtrue
に設定します。デフォルトでは、initialLoad
がfalse
に設定されており、初回(index=0
)のonLoad
は実行されません。
true
: スクロール量に関わらず、初回のonLoad
は実行され、提供されるindex
は0
から始まります。
false
: スクロールが一定に達するとonLoad
が実行され、提供されるindex
は1
から始まります。
編集可能な例
const [count, setCount] = useState<number>(0) const { ref, isFinish } = useInfiniteScroll({ onLoad: ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, initialLoad: true, }) return ( <VStack> {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} </VStack> )
開始するindex
を変更する
開始するindex
を変更する場合は、startIndex
に数値を設定します。デフォルトは、1
です。
編集可能な例
const [count, setCount] = useState<number>(50) const { ref, isFinish } = useInfiniteScroll({ onLoad: async ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, startIndex: 3, }) return ( <VStack> {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} </VStack> )
反転させる
反転させる場合は、isReverse
をtrue
に設定します。デフォルトは、false
です。
編集可能な例
const rootRef = useRef<HTMLDivElement>(null) const [count, setCount] = useState<number>(50) const { ref, isFinish } = useInfiniteScroll({ onLoad: async ({ index, finish }) => { console.log("onLoad", index) setCount((prev) => prev + 50) if (index >= 5) finish() }, rootRef, isReverse: true, }) return ( <VStack ref={rootRef} h="full" overflow="auto"> {!isFinish ? ( <Center ref={ref} w="full"> <Loading fontSize="2xl" /> </Center> ) : null} {Array(count) .fill(0) .map((_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> ))} </VStack> )
GitHubでこのページを編集する