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>
);
}