やりたいこと
直前のページからの遷移かどうかを簡易的に確認し、違っていたらトップに戻す。
例えばお問い合わせページの完了画面に直接アクセスされた(確認画面からの遷移でない)ときなどに使いたいテクニックです。
実装
react-routerでユーザーのインタラクションに依らないページ遷移を実現する方法としては以下が挙げられます。
props.history.push('/foo')
<Redirect to='/foo' />
ただし、上記のいずれかで遷移した場合、遷移した先では遷移元が不明なので、「本来想定しているページから遷移してきたか」が判別できません。
そこでちょっと加工してやります。
PageA.jsx
import { withRouter } from 'react-router';
class PageA extends React.Component {
constructor(props) {
super(props)
// NG
props.history.push('/page_b');
// OK
props.history.push({pathname: '/page_b', state: { referrer: '/page_a' }});
}
render() {
return <div></div>;
}
}
export default withRouter(PageA);
もしくは
PageA.jsx
import { Redirect } from 'react-router';
class PageA extends React.Component {
constructor(props) {
super(props)
}
render() {
return <Redirect to={{pathname: '/page_b', state: { referrer: '/page_a' }}} />;
}
}
export default PageA;
そして遷移先のページで
PageB.jsx
import { withRouter } from 'react-router';
class PageA extends React.Component {
constructor(props) {
super(props);
// PageAからの遷移でないと判断したときはトップページに飛ばす
if(!props.location.state.referrer) props.history.replace('/');
}
render() {
return (
<div>Page B</div>
)
}
}
export default withRouter(PageB);
解説
props.historyは以下の4つのプロパティを持っています。
- pathname
- hash
- search
- state
このうちstateは任意の値を持たせることができるので
{ referrer: '/page_a' }
という値をprops.history.push()ないしRedirect toする際に設定してやり、
遷移先で取得→判別するという流れになります。