React Router でページ遷移時にスクロールをトップに戻す
問題
React Router を使用してページ間を遷移するとき、ブラウザのスクロール位置が保持されることがあります。これにより、ユーザーが以前に閲覧していたページのスクロール位置に戻ってしまうことがあります。
解決策
ページ遷移時にスクロールをトップに戻すには、次の方法を使用できます。
useEffect Hook を使用
useEffect
Hook を利用して、コンポーネントがマウントされたときにスクロールをトップに戻します。
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
// コンポーネントのレンダリング
);
}
React Router の scrollToTop メソッドを使用
React Router v6 以降では、useLocation
Hook と scrollToTop
メソッドを組み合わせて、ページ遷移時にスクロールをトップに戻すことができます。
import { useLocation, scrollToTop } from 'react-router-dom';
function MyComponent() {
const location = useLocation();
useEffect(() => {
scrollToTop();
}, [location]);
return (
// コンポーネントのレンダリング
);
}
カスタムフックの作成
ページ遷移時にスクロールをトップに戻す処理を再利用するために、カスタムフックを作成することもできます。
import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
function useScrollToTop() {
const [hasScrolled, setHasScrolled] = useState(false);
const location = useLocation();
useEffect(() => {
if (!hasScrolled) {
window.scrollTo(0, 0);
setHasScrolled(true);
}
}, [location, hasScrolled]);
}
function MyComponent() {
useScrollToTop();
return (
// コンポーネントのレンダリング
);
}
- カスタムフックを使用することで、ページ遷移時のスクロール処理を複数のコンポーネントで共通化することができます。
- React Router v6 以降の
scrollToTop
メソッドは、ブラウザのネイティブのスクロール機能を使用してスムーズなスクロールを実現します。 useEffect
の第 2 引数にlocation
を依存配列として指定することで、ページ遷移が発生したときにスクロールがトップに戻されます。
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
// コンポーネントのレンダリング
);
}
- 空の依存配列 []
このuseEffect
はコンポーネントが最初にマウントされたときだけ実行されます。 - window.scrollTo(0, 0)
ブラウザのスクロール位置を (0, 0) に設定し、ページのトップにスクロールします。 - useEffect Hook
コンポーネントがマウントされたときに実行される効果的な処理を定義します。
import { useLocation, scrollToTop } from 'react-router-dom';
function MyComponent() {
const location = useLocation();
useEffect(() => {
scrollToTop();
}, [location]);
return (
// コンポーネントのレンダリング
);
}
- 依存配列 [location]
location
が変更されたとき (ページ遷移が発生したとき) にuseEffect
が実行され、スクロールがトップに戻ります。 - scrollToTop メソッド
ブラウザのスクロール位置をトップに設定します。 - useLocation Hook
現在の URL パスを取得します。
import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
function useScrollToTop() {
const [hasScrolled, setHasScrolled] = useState(false);
const location = useLocation();
useEffect(() => {
if (!hasScrolled) {
window.scrollTo(0, 0);
setHasScrolled(true);
}
}, [location, hasScrolled]);
}
function MyComponent() {
useScrollToTop();
return (
// コンポーネントのレンダリング
);
}
- MyComponent
カスタムフックを使用することで、ページ遷移時のスクロール処理を簡単に適用できます。 - useEffect
ページ遷移が発生したときに、スクロールがまだ実行されていない場合はスクロールをトップに戻します。 - hasScrolled 状態
スクロールが一度でも実行されたかどうかを管理します。 - カスタムフック useScrollToTop
ページ遷移時にスクロールをトップに戻す処理をカプセル化します。
BrowserRouter の scrollBehavior プロパティを使用
React Router v6 以降では、BrowserRouter
コンポーネントの scrollBehavior
プロパティを使用して、ページ遷移時のスクロール挙動をカスタマイズできます。
import { BrowserRouter } from 'react-router-dom';
function App() {
return (
<BrowserRouter scrollBehavior={() => ({ behavior: 'smooth', top: 0 })}>
{/* アプリケーションのルートコンポーネント */}
</BrowserRouter>
);
}
- top: 0
スクロール位置をページのトップに設定します。 - behavior: 'smooth'
スクロールをスムーズにアニメーションします。 - scrollBehavior プロパティ
ページ遷移時のスクロール位置を指定する関数を受け取ります。
react-router-scroll-to-top パッケージを使用
サードパーティのパッケージ react-router-scroll-to-top
を使用して、ページ遷移時にスクロールをトップに戻すことができます。
import { ScrollToTop } from 'react-router-scroll-to-top';
function App() {
return (
<BrowserRouter>
<ScrollToTop />
{/* アプリケーションのルートコンポーネント */}
</BrowserRouter>
);
}
- ScrollToTop コンポーネント
ページ遷移時に自動的にスクロールをトップに戻します。
react-scroll パッケージを使用
react-scroll
パッケージを使用すると、ページ内の任意の要素にスクロールする機能を実装できます。
import { animateScroll as scroll } from 'react-scroll';
function MyComponent() {
const scrollToTop = () => {
scroll.scrollToTop();
};
// ページ遷移時にスクロールをトップに戻す処理を呼び出す
useEffect(() => {
scrollToTop();
}, []);
return (
// コンポーネントのレンダリング
);
}
- animateScroll.scrollToTop()
ページのトップにスクロールします。
react-scroll
パッケージは、ページ内の任意の要素にスクロールする機能を提供しますが、ページ遷移時に自動的にスクロールをトップに戻すには、追加の処理が必要になります。react-router-scroll-to-top
パッケージは、シンプルな実装を提供します。BrowserRouter
のscrollBehavior
プロパティは、アプリケーション全体に適用されるため、すべてのページ遷移でスクロールがトップに戻ります。
javascript reactjs react-router