[フロントエンド] 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をフォローして貰えたら嬉しいです ^ ^
最後までご覧頂きましてありがとうございました!