概要
nextjsのlayout下でページ遷移を行う際、Layoutの再レンダリングは行われませんが、画面のスクロール位置はリセットされてしまうようです。Layout下でモーダルウィンドウを用いて一時的な情報を画面上に表示したい際の解決策を紹介します。
解決策
Layout.tsx上でスクロール位置を保持し、ページ遷移(URL変化)を検知したらスクロール位置を戻す実装を行うことで解決できそうです。
(スクロール位置をwindow.scrollYが持っているか、document.scrollingElement.scrollTopが持っているかで若干実装が異なります。)
./Layout.tsx(documentのエレメントがスクロールする場合)
export default function Layout({
children,
}: {
children: ReactNode;
}) {
const pathname = usePathname();
const [scrollPosition, setScrollPosition] = useState(0);
const handleScroll = () => {
setScrollPosition(document.scrollingElement.scrollTop);
console.log(document.scrollingElement.scrollTop);
};
// 初期化
useEffect(() => {
// イベント登録
document.addEventListener('scroll', handleScroll);
// イベント解除
return () => {
document.removeEventListener('scroll', handleScroll);
};
}, []);
// ページ遷移時
useEffect(() => {
console.log(pathname);
document.scrollingElement.scrollTop = scrollPosition;
}, [pathname]);
return (
<>
{children}
</>
);
./modal/page.tsx
export default function Modal() {
return (
<>
popup
</>
);