過去に、イベント発火したら、特定のスクロール箇所が表示される要件があった。 スムーズにスクロールするのではなく、瞬時に表示したかった。 その時は、refを使ってスクロール箇所を特定して、表示できるようにした。 その時に、refだけを用いて、特定の高さだけ下に移動する処理にした。 困難だったのは、drawerを開いてもrefがnullのままだったため、scrollIntoViewが発火せずに何も起こらなかった。 そのため、必要なUIとrefを子コンポーネントに切り出す事でrefがnullでは無くなったので解決した。
今回は、Drawerを開く際に、スクロール処理を行うカスタムopenDrawerを作成した。 その際に、スクロール処理を行う箇所を特定するために、IDやdata属性を使って要素を特定した。 その後、スクロール処理を行うカスタムopenDrawerを作成した。
const scrollContainerRef = useRef<HTMLDivElement | null>(null)
// Drawerを開く際にスクロール処理を行うカスタムopenDrawer
const openDrawerAndScroll = useCallback(() => {
originalOpenDrawer() // 元のロジックでDrawerを開く
// @see: https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame
requestAnimationFrame(() => {
// IDやdata属性を使って要素を特定する (例: "filter-item-3-4")
const elementId = "filter-item-year-month"←
firstCheckedElement = document.getElementById(elementId)
if (firstCheckedElement) {
firstCheckedElement.scrollIntoView({
behavior: 'instant',
block: 'center', // 要素が中央に来るようにスクロール
})
}
}
}
return (
<Drawer isOpen={isDrawerOpen} onClose={closeDrawer}>
<h2 className="mb-4 text-xl font-bold text-gray-800">フィルター</h2>
<div
ref={scrollContainerRef}
className="h-[calc(100%-60px)] overflow-y-auto"
>
{Object.entries(months).map(([month, checked]) => (
// idを年月にする
<div key={month} id={"filter-item-year-month"}>{month}</div>
))}
</div>
</Drawer>
)