aknow2

自分の興味のある事を連々と(プログラミング、モバイルアプリ、プログラミング教育)

React Router(v4)でcomponentクラス外から手動でページ遷移を行う。

まずReact Router v4 基本的なページ遷移の方法からです。
やり方は以下で出来ます。

// タグで指定する
class Hoge extends React.component {
  render (): JSX.Element {
    return <Link to='/my/link'>Link</Link>;
  }
}

// historyを利用する
class Hoge2 extends React.component {
   
   handleClick () {
        this.props.history.push('/my/link');
   }

   render (): JSX.Element {
    return <button onClick={this.handleClick}> Link </button>
  }
}

ただ、これらは<Router>の配下のComponent、又はwithRouter利用したComponent内でしか利用出来ません。
Componentの外からページ遷移をしたい場合、どの様にすれば良いか一例を紹介したいと思います。
(例はTypescriptで書いていますが、Javascriptでも殆ど変わらないと思います。

先ほどの例で this.props.history.push('my/link') とありましたが、
実際にページ遷移を実行しているのはhistoryオブジェクトです。
このhistoryオブジェクトをどうにかして、何処からでもアクセス出来るようにする
というのが今回とった方法です。

何処からでもアクセスさせるには
createBrowserHistoryという関数を利用して
historyオブジェクトを自前で生成しexportします。
これで何処からでもhistoryオブジェクトが参照出来るようになります。
今回はhistory.tsというファイルを作成して実装してます。

//history.ts
import createHistory from 'history/createBrowserHistory';
const History = createHistory();
export default History;

次にhistoryをReact Routerに設定します。
設定するには, <Router>のプロパティであるhistoryに指定すると出来ます。
下記はindex.tsがこのReactAppのルートファイルである場合の例です。

// index.ts
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import { Router, Route } from 'react-router-dom';
import history from './history'; // <- 先ほど作ったhistoryをimport

ReactDOM.render(
        <Router history={history}> // <-ここがポイント
          <Route path={'/'} component={App} />
        </Router>
  document.getElementById('root') as HTMLElement
);

下準備はこれでOKです。
ページ遷移を実行したい箇所でhistoryをインポートして pushメソッドを呼び出せばページ遷移が出来ます。

import history from './history.ts' 
class Linker {

    linkToMyLink() {
        history.push('/my/link');
    }

}

ただ、これをすると何処からでもページ遷移が出来てしまうので
設計時にどのレイヤーでページ遷移をすべきかちゃんと考えたいですね。 以上です。