0
votes

In my home page component, this.context.router is not defined. I am using the following dependencies:

"@material-ui/core": "^3.9.3",
"@material-ui/icons": "^3.0.2",
"history": "^4.9.0",
"moment": "^2.24.0",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.0",
"react-scripts": "2.1.8",
"react-swipeable-views": "^0.13.1"

And my index.js is:

import React from 'react';
import ReactDOM from 'react-dom';
import {Switch, Router, Route, BrowserRouter } from 'react-router-dom';
import {MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import * as serviceWorker from './serviceWorker';
import UserApp from 'components/App.js';
ReactDOM.render((
                  <MuiThemeProvider theme={createMuiTheme({typography: { useNextVariants: true, },})}>
                    <BrowserRouter>
                      <Switch>
                          <Route path='/' component={UserApp} />                    
                      </Switch>   
                    </BrowserRouter>
                  </MuiThemeProvider>
                ), document.getElementById('root'));

serviceWorker.register();

components/App.js contents are:

import React, { Component } from 'react';
import Header from 'components/layout/Header.js';
import Footer from 'components/layout/Footer.js';
import Main from 'components/layout/Main.js';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      navOpen: false
    };
  }
  openLeftNav=()=>{}
  render() {
    return (
      <div className="site-app">
        <Header {...this.props} openLeftNav={this.openLeftNav} />
        <Main />
        <Footer />
      </div>
    );
  }
}

export default App;

Main is our inner app route file. The structure of Main.js is:

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import HomePage from 'components/app/account/Home.js';

const Main = () => (
  <main>
    <Switch>
      <Route exact path='/' component={HomePage}/>
   </Switch>
  </main>
);   
export default Main;

And my Home.js file is:

import React from 'react';
import PropTypes from 'prop-types';
import classNames from "classnames";
import withStyles from "@material-ui/core/styles/withStyles";
import landingPageStyle from "assets/jss/landingPage.jsx";

    class Home extends React.Component {
          constructor(props, context) {
                super(props, context);
                this.state = {
                      expanded: null,
                }
          }
          componentDidMount() {}
          testFunction=()=>{
               console.log(this.context);
               this.context.router.history.push('/test-page');
          }

       render() {
        return (
               <div>
                <Button color="primary" onClick={this.testFunction}>Click Me</Button>
              </div>

            )
         }
    }

    Home.contextTypes = {
          router: PropTypes.object.isRequired
    };
    export default withStyles(landingPageStyle)(Home);

I want to navigate conditionally using this.context.route, Can anyone please help me why this.context.router is undefined? This code worked before with previous version of react[v16.3] react-router-dom[v4.2.2] and material-ui[v1.1.0], but now it is not working.

1
You need to wrap the withRouter hoc onto your component to gain access to history prop - reacttraining.com/react-router/web/api/withRouter - Shawn Yap
Is it necessary to use withRouter? I just want to know how it was working in my previous project has the same code without using withRouter? - Priyabrata Atha
I'm not sure how you're doing it in your last project but as far as I know, yes it is. Also, I can't tell where context is coming from. - Shawn Yap
My Previous project was same coding strcture as it is only the versions are different - react[v16.3] react-router-dom[v4.2.2] and material-ui[v1.1.0]. - Priyabrata Atha
Anyway I start using withRouter, and it worked. But still I want to know the reason, if you have any answer in future, that will help me Shawn Yap. Thank You. - Priyabrata Atha

1 Answers

1
votes

Same happened to me, I started using Link wich is provided by react-router-dom

import { Link } from 'react-router-dom';
import Button from '@material-ui/core/Button';

<Button component={Link} to="/test-page">
  About
</Button>

Another solution is injecting history, for example

...
import { withRouter } from 'react-router-dom';
class Home extends React.Component {
    testFunction=()=> this.props.history.push('/test-page');
    ...
}
export default withStyles(landingPageStyle)(withRouter(Home));