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/withRouterShawn 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));