Reactで作成するアプリケーションでは、リンク経由でページ遷移をしても画面が書き換わるだけでページのスクロールポジションまでは初期化されません。
react-routerを利用している場合、ページ遷移をするタイミングで任意の処理を実行できます。この処理を使ったスクロールポジションの初期化方法を解説します。
react-routerのonChangeコールバックを使う(react-router v3以下)
react-routerの onChange
コールバックを使います。
onChange
コールバックは、ページのパスが書き変わった度に実行されます。
次のコードを見てください。
import React from "react";
import { Route } from "react-router";
import App from "components/App";
import Profile from "components/Profile";
// onChangeに渡すコールバック
const handleLocationChange = (prevState, nextState) => {
if (nextState.location.action !== "POP") {
window.scrollTo(0, 0);
}
};
export default (
<Provider store={store}>
<Router history={history}>
{/* onChange */}
<Route path="/" component={App} onChange={handleLocationChange}>
<Route path="profile" component={Profile} />
...
</Route>
</Router>
</Provider>
);
ページが進む度に、window.scrollTo(0, 0)
を実行するコールバック関数を渡しています。
これは、pathが /
配下のURL全てに適用されます。
その他にも、ページに入った時に実行される onEnter
や、ページを抜ける時に実行する onLeave
などもあります。
【参考】Scroll to top on route change?
react-router v4の場合
v4の場合はAPIが変わるため、locationの変更でスクロールするためのコンポーネントを定義します。
import { Component } from 'react'; import { withRouter } from 'react-router'; class ScrollToTop extends Component { componentDidUpdate(prevProps) { if (this.props.location.pathname !== prevProps.location.pathname) { window.scrollTo(0, 0); } } render() { return this.props.children; } } export default withRouter(ScrollToTop);
propsから渡ってくる location
をみてパスが変わったら window.scrollTo(0, 0)
を実行する実装です。
このScrollToTopコンポーネントは props.children
を返すのでルートコンポーネントをラップします。
function App() { return ( <Router> <ScrollToTop> <App /> </ScrollToTop> </Router> ); }