質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.03%

react-router でのページ遷移について

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 4,037

score 10

前提・

react.js(materialUI)でアプリ作成をしていますが、react-routerを使ったページ遷移ができません。

発生している問題・エラーメッセージ

NavBar.jsコンポーネントをApp.jsにインポートしている。
NavBar.jsでは、ページ上部のバーを実装しており、
Homeボタン、Aboutボタン、Loginボタンを押すとそれぞれのページに遷移する
仕様を目指している。
index.jsにreact-routerでルーティング情報を記載。

onClickを使い、実装をしたい。

```
エラーメッセージ
TypeError: Cannot read property 'push' of undefinedと表示されます。

NavBar.jsがindex.jsのルーティング対象ではないからpropsが渡せないのか、
原因が不明です。

該当のソースコード

<index.js>
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import About from './About';
import Login from './Login';
import { browserHistory } from 'react-router';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom"
import './index.css';

ReactDOM.render(
<Router history={browserHistory}>
<Switch>
<Route exact path="/" component={App} />
<Route path="/about" component={About} />
<Route path="/login" component={Login} />
</Switch>
</Router>
,document.getElementById('root')
);

<NavBar.js>
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import {BrowserRouter as Router} from 'react-router-dom';
import { withRouter } from 'react-router';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';

const styles = {
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
};

class NavBar extends React.Component {
constructor(props){
super(props);
};

static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}

handleToHomePage = () => {
console.log('AppBar props')
console.log(this.props)
console.log(this.props.history)
this.props.history.push('/')
}

handleToAboutPage = () => {
this.props.history.push('/about')
}
}

handleToLoginPage = () => {
this.props.history.push('/login')
}

const { classes } = props;

render(){
const { classes } = this.props;

return (
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" className={classes.grow}>
News
</Typography>
<Router>
<div>
<Button color="inherit" onClick={this.handleToHomePage}>Home</Button>
<Button color="inherit" onClick={this.handleToAboutPage}>About</Button>
<Button color="inherit" onClick={this.handleToLoginPage.bind(this)}>Login</Button>
</div>
</Router>
</Toolbar>
</AppBar>
</div>
);
}
}

NavBar.propTypes = {
classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(NavBar);withRouter(NavBar);

<App.js>
import React, { Component } from 'react';

import NavBar from './NavBar';
import './App.css';

class App extends Component {
constructor(props) {
super(props)
this.state = {
open: false
}
}

render() {
return (
<div>
<NavBar/>
</div>
);
}
}

export default App;

言語名

React.js  Material-UI

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

それぞれのバージョンは下記の通りです。
"react-dom": "^16.6.1",
"react-router": "^3.2.1",
"react-router-dom": "^4.3.1",

react初心者のため、非常に困っています。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

pushは、withRouterで追加されるpropです。
ご質問のソースの書き方では、withRouterが効いていない状態です。

これでどうでしょうか?

export default withStyles(styles)(withRouter(NavBar));

または、

export default withRouter(withStyles(styles)(NavBar));

withStylesやwithRouterは、HOC関数(withStylesは正確にはHOC関数を生成するFactoryですが)で、引数として受け取ったComponentを拡張して、拡張後のComponentを戻り値として返すものです。

複数利用する場合は、ネストさせて利用してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/15 12:25

    この方法では、解決しなかったですか??

    キャンセル

  • 2018/12/15 16:59

    ご連絡が遅れ申し訳ございません。
    そして、早速回答をくださってありがとうございました。
    試したのですが、やはり同じ文言のエラーが出てしまいます。
    検索ボックスに直にhttp://localhost:3000/aboutなどと入れるとページ遷移できますが、
    NavBar.jsに書いたボタンをクリックして各ページに行こうとすると、どうしてもエラーが出てしまいます。

    キャンセル

  • 2018/12/15 17:02

    NavBar.jsの最後に export default withRouter(withStyles(styles)(NavBar)); と export default withStyles(styles)(withRouter(NavBar)); の両方入れて見て試しましたが、エラーが出ています。

    キャンセル

  • 2018/12/15 17:18

    この回答の変更をしたとき、Loginリンクだけ動作しませんか?

    もしそうなら、onClickのハンドラーを設定する際に、Loginと同じようにthisをbindするか、
    もしくは、

    onClick={() => {this.handleToLoginPage()}}

    のように、アロー関数を定義して設定してみてください。

    現在のコーディングだと、thisが<button/>になるように思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る