react-router画面遷移時のスクロール位置を操作する
前のページのスクロール位置が残る
react-routerはURLのハッシュを用いて画面遷移を表現していますが、実際のルーティングは固定だったりします。
なので、こんな気遣いをしないと遷移後に最上部にスクロールしてくれなかったりします。
<Router onUpdate={() => window.scrollTo(0, 0)}> : </Router>
新しいプロジェクトを作成したときに、どうやってたっけ?と思ってしまったのでメモがてら残しておきます(^_^;)
ちなみに、ルーティングにパラメータを付けて、デフォルトのスクロール位置を変更させたい時はこちらのような共用モジュールを作成して対処しています。
自分の位置を返すComponent
import React, { Component } from 'react'; import PropTypes from 'prop-types'; export default class Scroller extends Component { componentDidMount() { const { active, callback } = this.props; if (active) { callback(this.scroller.offsetTop); } } componentWillUnmount() { this.scroller = null; } render() { return ( <div ref={e => (this.scroller = e)} /> ); } } Scroller.propTypes = { active: PropTypes.bool, callback: PropTypes.func, }; Scroller.defaultProps = { active: false, callback: null, };
Scrollerはスクロールさせたい位置にマーカー的に配置します。
activeの場合のみコールバックで自分の位置を返します。
使い方はこんな感じです。
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Scroller from './Scroller'; export default class Clips extends Component { componentDidUpdate() { if (this.position) { window.scrollTo(0, this.position); this.position = null; } } render() { const { location } = this.props; return ( <div> <Scroller active={location.query.content === 'content1'} callback={e => (this.position = e)} /> <div> コンテンツ1 </div> <Scroller active={location.query.content === 'content2'} callback={e => (this.position = e)} /> <div> コンテンツ2 </div> </div> ); } } Clips.propTypes = { location: PropTypes.shape().isRequired, };
ルーティングに併せてスクロールできるパッケージもありますね。 こちらは座標指定が必要なので、併せて利用できるかと思います。 www.npmjs.com