--- title: InfiniteScrollArea description: "`InfiniteScrollArea`は、無限スクロール機能を提供するコンポーネントです。このコンポーネントは、コンポーネントの終わりに達したときに次のデータセットを自動的に読み込み、表示することで、スムーズなスクロール体験を提供します。" links: - style: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/components/infinite-scroll-area/infinite-scroll-area.style.ts - source: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/components/infinite-scroll-area - storybook: https://yamada-ui.github.io/yamada-ui?path=/story/components-infinitescrollarea--basic --- ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ## 使い方 ```tsx import { InfiniteScrollArea } from "@yamada-ui/react" ``` ```tsx import { InfiniteScrollArea } from "@/components/ui" ``` ```tsx import { InfiniteScrollArea } from "@workspace/ui" ``` ```tsx ``` ### ビューポートを指定する ビューポートを指定する場合は、`rootRef`に`ref`を設定します。 :::note `rootRef`が設定されない場合は、ブラウザのビューポートが使用されます。 ::: ```tsx const rootRef = useRef(null) const [count, setCount] = useState(50) const resetRef = useRef<() => void>(noop) return ( } resetRef={resetRef} rootRef={rootRef} onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### rootMarginを設定する [rootMargin](https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API#rootmargin)を設定する場合は、`rootMargin`に文字列を設定します。 ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### thresholdを設定する [threshold](https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API#threshold)を設定する場合は、`threshold`に数値を設定します。 ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### 初回に読み込む 初回に読み込む場合は、`initialLoad`を`true`に設定します。デフォルトでは、`initialLoad`が`false`に設定されており、初回(`index=0`)の`onLoad`は実行されません。 `true`: スクロール量に関わらず、初回の`onLoad`は実行され、提供される`index`は`0`から始まります。\ `false`: スクロールが一定に達すると`onLoad`が実行され、提供される`index`は`1`から始まります。 ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### 開始するindexを変更する 開始する`index`を変更する場合は、`startIndex`に数値を設定します。デフォルトでは、`1`が設定されています。 ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### 方向を変更する 方向を変更する場合は、`orientation`に`"vertical"`または`"horizontal"`を設定します。デフォルトは、`"vertical"`です。 ```tsx const [count, setCount] = useState(50) return ( <> {Array(count) .fill(0) .map((_, index) => ( ))} ) ``` ### 反転させる 反転させる場合は、`reverse`を`true`に設定します。デフォルトは、`false`です。 ```tsx const rootRef = useRef(null) const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### 無効にする 無効にする場合は、`disabled`を`true`に設定します。これは、特定の条件下でスクロールに合わせて`onLoad`を実行したくない場合に有効です。 ```tsx const [disabled, setDisabled] = useState(false) const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} borderWidth="1px" h="sm" overflowY="auto" p="lg" rounded="l2" > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### リセットする `index`をリセットする場合は、`resetRef`に`ref`を設定します。設定された`ref`にコールバック関数が付与されるので、それを実行します。 :::warning `resetRef`のコールバックを実行すると、スクロールもリセットされます。 ::: ```tsx const resetRef = useRef<() => void>(noop) const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} borderWidth="1px" h="sm" overflowY="auto" p="lg" rounded="l2" > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### スクロールの終わりに要素を表示する スクロールの終わりに要素を表示する場合は、`finish`に`ReactNode`を設定します。 ```tsx const [count, setCount] = useState(50) return ( 俺のドリルは!天を作るドリルだああああっ!!} loading={} onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 1) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### トリガーをカスタマイズする トリガーをカスタマイズする場合は、`triggerProps`にpropsを設定します。 ```tsx const [count, setCount] = useState(50) return ( } onLoad={async ({ finish, index }) => { console.log("load", index) await wait(5000) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### ローディングをカスタマイズする ローディングをカスタマイズする場合は、`loading`に`ReactNode`を設定します。 ```tsx const [count, setCount] = useState(50) return ( 一回転すればほんの少しだけ前に進む、それがドリルなんだよ!!} onLoad={async ({ finish, index }) => { console.log("load", index) await wait(5000) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ## Props | Prop | Default | Type | Description | | -------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `as` | - | `As` | The HTML element to render. | | `asChild` | - | `boolean` | Merges its props onto its immediate child. | | `css` | - | `CSSObject \| CSSObject[]` | The CSS object. | | `colorScheme` | - | `"amber" \| "black" \| "blackAlpha" \| "blue" \| "cyan" \| "danger" \| "emerald" \| "error" \| "flashy" \| "fuchsia" ...` | Set color scheme variables. | | `behavior` | - | `ScrollBehavior` | Determines whether scrolling is instant or animates smoothly. | | `disabled` | `false` | `boolean` | If `true`, the infinite scroll is disabled. | | `finish` | - | `ReactNode` | The infinite scroll area finish to use. | | `indexRef` | - | `RefObject<(index: number) => void>` | Ref to a reset index function. | | `initialLoad` | `false` | `boolean` | If `true`, invoke `onLoad` function for the first time. | | `loading` | - | `ReactNode` | The infinite scroll area loading to use. | | `onLoad` | - | `({ entry, finish, index }: { finish: () => void; index: number; entry?: IntersectionObserverEntry \| undefined }) => void \| Promise` | The callback invoked when trigger is intersect. | | `orientation` | `"vertical"` | `"horizontal" \| "vertical"` | The orientation of the infinite scroll. | | `resetRef` | - | `RefObject<(index?: number \| undefined, runScroll?: boolean \| undefined) => void>` | Ref to a reset function. | | `reverse` | `false` | `boolean` | If `true`, reverse direction. | | `rootMargin` | - | `string` | Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). | | `rootRef` | - | `RefObject` | The element that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if `null`. | | `startIndex` | `1` | `number` | If set the `onLoad` function will start from the given index. If `initialLoad` is `true`, index starts from `0`. | | `threshold` | - | `number \| number[]` | Either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed. | | `triggerProps` | - | `HTMLStyledProps` | Props for infinite scroll area trigger component. |