[フロントエンド] React Routerで、子要素でもhistory.pushを使いたい(withRouterの利用)
こんにちは、@yoheiMuneです。
React.jsの任意のコンポーネントから、React Routerの
Drawer.jsを以下のように改造します。
上記の変更点1〜4を実装することで、Drawer.jsの中でも
https://reacttraining.com/react-router/web/api/withRouter
最後になりますが本ブログでは、フロントエンド、Swift、PHP、Node.js、Python、Java、Linux、インフラ、Go言語、機械学習、などの技術トピックを発信をしていきます。「プログラミングで困ったその時の、解決の糸口に!」そんな目標でブログを書き続けています。ぜひ、本ブログのRSSやTwitterをフォローして貰えたら嬉しいです ^ ^
最後までご覧頂きましてありがとうございました!
React.jsの任意のコンポーネントから、React Routerの
match、location、historyを使えるようにする方法を、ブログに書きたいと思います。
目次
対象のバージョン
React Routerのバージョンは、v4以降が対象です。v3以前とはかなり違うので、対象バージョンにご注意ください。何が問題か
例えば、以下のルーティングがあるとします。
import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Switch } from "react-router-dom"
import Thread from './Thread'
import Todo from './Todo'
class AppRouter extends Component {
render() {
return (
<Router>
<Switch>
<Route path="/thread" component={Thread}/>
<Route path="/todo" component={Todo}/>
</Switch>
</Router>
)
}
}
export default AppRouter
この場合、ThreadやTodoのルーティング対象のコンポーネント(=ReactRouterのルーティングに指定するコンポーネント)からは、this.props.historyなど、ReactRouterの機能にアクセスすることが可能です。
// Thread.js
import React, { Component } from 'react'
class Thread extends Component {
doSomething() {
// React Routerの機能にアクセスできる.
this.props.history.push('/todo')
}
}
しかし、ルーティング対象でないコンポーネント(=ルーティング対象のコンポーネントの子要素など、以下の例ではDrawer.js)の場合、this.props.historyでアクセスできません。
// Drawer.js
import React, { Component } from 'react'
class Drawer extends Component {
doSomething() {
// 子要素からは、React Routerの機能にアクセスできない.
this.props.history.push('/todo') // ERROR : this.props.history が undefined
}
}
export default Drawer
// Todo.js
import React, { Component } from 'react'
import Drawer from './Drawer'
class Todo extends Component {
render() {
// 子要素として利用
return <Drawer/>
}
}
今回は、Drawer.jsのようなサブコンポーネントでもReactRouterの機能を使えるようにしたい、という話です。子コンポーネントでもReact Routerの機能を使う
対処法はいくつかありますが、withRouterを使うとシンプルに実装できます。Drawer.jsを以下のように改造します。
// Drawer.js
import React, { Component } from 'react'
import PropTypes from 'prop-types' // [変更点1] importを追加
import { withRouter } from 'react-router' // [変更点2] importを追加
class Drawer extends Component {
// [変更点3] propTypesの定義追加
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}
doSomething() {
// React Routerの機能にアクセスできた!
this.props.history.push('/todo')
}
}
// [変更点4] withRouterでラッピング
export default withRouter(Drawer)
変更点1,2でimportするモジュールは、npm installでインストールしてください。上記の変更点1〜4を実装することで、Drawer.jsの中でも
matchやlocationやhistoryにアクセスできるようになります。便利ですね。参照ドキュメント
公式にも説明がありますので、そちらも合わせてご確認ください。https://reacttraining.com/react-router/web/api/withRouter
最後に
React Routerの機能は奥が深くて、学んでいて楽しいですね。しっかりと実世界に生かしていきたいところです。最後になりますが本ブログでは、フロントエンド、Swift、PHP、Node.js、Python、Java、Linux、インフラ、Go言語、機械学習、などの技術トピックを発信をしていきます。「プログラミングで困ったその時の、解決の糸口に!」そんな目標でブログを書き続けています。ぜひ、本ブログのRSSやTwitterをフォローして貰えたら嬉しいです ^ ^
最後までご覧頂きましてありがとうございました!






