15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

react-routerでページ遷移の整合性を担保する

Posted at

やりたいこと

直前のページからの遷移かどうかを簡易的に確認し、違っていたらトップに戻す。
例えばお問い合わせページの完了画面に直接アクセスされた(確認画面からの遷移でない)ときなどに使いたいテクニックです。

実装

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する際に設定してやり、
遷移先で取得→判別するという流れになります。

15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?