react-router@v4対応したので雑に晒す

  • 45
    いいね
  • 1
    コメント

react-router@v4対応しんどかったから備忘録残す。
既存をバージョンアップするだけだと絶対死ぬ。危険。

変更点

破壊的な変更が入った。今までの手法は腐った。
マニュアル見ながら書かないとハマる。見てもハマる。

  • パッケージ名がreact-routerからreact-router-domになった
  • URL起因のパラメータ周りの呼び方変更 this.props.params -> this.props.match.params
  • Route定義がしれっと無名関数になってる
  • browserhistoryの取り扱い

material-uiと連携する時、<Route.component>に、
Templateとして<MuiThemeProvider>を渡してたけど、
props.childrenで渡すなって警告が出たから諦めて別実装にした。

アップデート方法

npm un -S react-router && npm i -S react-router-dom

差分

v3からv4への修正点まとめたので晒す

diff --git a/package.json b/package.json
index 249974e..25f88b1 100644
--- a/package.json
+++ b/package.json
@@ -97,8 +97,7 @@
     "react-ga": "2.1.2",
     "react-helmet": "^4.0.0",
     "react-konva": "1.1.1",
-    "react-router": "3.0.2",
+    "react-router-dom": "4.0.0",
     "react-tap-event-plugin": "2.0.1",
     "react-window-resize-listener": "1.1.0"
   }
diff --git a/src/components/Config/routes.jsx b/src/components/Config/routes.jsx
index 84e32e1..e5cabc1 100644
--- a/src/components/Config/routes.jsx
+++ b/src/components/Config/routes.jsx
@@ -1,19 +1,16 @@
 import React from 'react';
-import { Route, IndexRoute, Redirect } from 'react-router';
+import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom';

-import Template from '../Templates/Template';
 import Content from '../Templates/Content';

-const routes = (
-  <Route path="/" component={Template}>
-    <IndexRoute component={Content} />
-
-    <Route path="/uid" component={Content}>
-      <Route path=":uid" />
-    </Route>
-
-    <Redirect from="*" to="/" />
-  </Route>
+const routes = () => (
+  <Router>
+    <Switch>
+      <Route exact path="/" component={Content} />
+      <Route exact path="/uid/:uid" component={Content} />
+      <Redirect from="*" to="/" />
+    </Switch>
+  </Router>
 );

 export default routes;
diff --git a/src/components/Templates/Content/index.jsx b/src/components/Templates/Content/index.jsx
index d614360..6ae9a0b 100644
--- a/src/components/Templates/Content/index.jsx
+++ b/src/components/Templates/Content/index.jsx
@@ -1,6 +1,5 @@
 import React from 'react';
 import Helmet from 'react-helmet';
-import { browserHistory } from 'react-router';
 import Config from '../../Config/index';
 import Sidebar from '../../Sidebar';
 import Header from '../../Header';
@@ -11,8 +10,7 @@ import '../../Utils/common.css';
 class Content extends React.Component {
   constructor(props) {
     super(props);
-
-    const { params } = this.props;
+    const params = this.props.match.params;

     this.state = {
       uid: params.uid || '',
@@ -24,11 +22,12 @@ class Content extends React.Component {
     this.setState({ uid: v });

     const url = (v === '') ? '/' : `/uid/${v}`;
-    browserHistory.push(url);
+    this.props.history.push(url);
   }

   render() {
-    const { params } = this.props;
+    const params = this.props.match.params;
+    const { uid } = this.state;

     return (
       <div id="outer-container">
@@ -42,14 +41,20 @@ class Content extends React.Component {
 Content.propTypes = {
-  params: React.PropTypes.shape().isRequired,
+  history: React.PropTypes.shape().isRequired,
+  match: React.PropTypes.shape({
+    params: React.PropTypes.shape().isRequired,
+  }).isRequired,
 };

 export default Content;
diff --git a/src/index.jsx b/src/index.jsx
index a4c5050..2b48e9e 100644
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -1,21 +1,14 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
 import injectTapEventPlugin from 'react-tap-event-plugin';
-import { Router, browserHistory } from 'react-router';
-import routes from './components/Config/routes';
+import Routes from './components/Config/routes';
 import './main.css';
-
-const history = browserHistory;
-
-history.listen((location) => {
-  setTimeout(() => {
-    if (location.action === 'POP') return;
-    window.scrollTo(0, 0);
-  });
-});
+import Template from './components/Templates/Template';

 window.React = React;
 injectTapEventPlugin();
-ReactDOM.render((
-  <Router history={history} routes={routes} />
-), document.getElementById('root'));
+ReactDOM.render(
+  <Template>
+    <Routes />
+  </Template>
+  , document.getElementById('root'));