Matt
Matt

Reputation: 1609

Getting TypeError with React Router

I'm trying to implement the latest version of React Router (v.4.3.1) in Material UI Tabs, but getting the following error: TypeError: Cannot read property 'location' of undefined. I believe I need to use some sort of location history, but not sure of the implementation given the updates to React Router.

UPDATE

I've managed to fix the location of undefined issue and get the navbar and content to show by using BrowseRouter as Router, but now the navbar links are not showing in the navbar. There isn't any logic to show or hide the links, so not sure whats causing them to not show up.

App.js

import React, { Component } from "react";
import Main from './Main';
import { Router, Route, Switch, Link } from 'react-router-dom';

class App extends Component {
  constructor() {
    super();
    this.state = {
      appTitle: "App"
    };
  }

  componentDidMount() {
    document.title = this.state.appTitle;
  }

  render() {
    return (
      <ThemeProvider theme={lightTheme}>
       <Router>
         <Switch>
           <Route component={Main} exact path="/" />
         </Switch>
       </Router>
      </ThemeProvider>
    );
  }
}

export default App;

Main.js

import React from 'react';
import PropTypes from 'prop-types';
import { NavBar } from "./Components/Navbar/";

const GetNavBar = props => {
  return (<NavBar appTitle={props.appTitle} />);
}

const Main = props => {
  return (
    <div className={props.classes.root}>
    <GetNavBar appTitle={props.appTitle} { ...data.appHeader } />
    <GetPageComponents {...props} data={data}/>
    </div>
)};

Main.propTypes = {
  onClose: PropTypes.func
};

export default withStyles(styles)(Main);

Navbar.js

import React from "react";
import { Tabs, Tab } from 'tabs';
import PropTypes from 'prop-types';
import { Router } from 'react-router-dom';

const TabLink = linkProps => (
    <a {...linkProps}>{linkProps.linklabel}</a>
);

function renderTab({ getTabProps }) {
const { className, label, ...rest } = getTabProps();
return (
    <Tab
        className={`${className}`}
        component={TabLink}
        linklabel={label}
        to={TabLink}
        {...rest}
    />
 );
}

renderTab.propTypes = {
   getTabProps: PropTypes.func
};

const NavBar = ({onChange, onDeselect, classes}, props) => {
  return (
    <div className={styles.headerContainer}>
    <AppHeader
        data-testid="app-header-default-example"
        position="static"
        className={styles.root}
        getTabProps={({ getTabProps }) => (
          <div {...getTabProps({})}>
          <Router>
            <Tabs>
              <Tab label="Home" component={renderTab} exact to="/" />
              <p className={styles.headerAppTitle}>{props.appTitle} . 
              </p>
            </Tabs>
          </Router>
          </div>
        )}
      />
    </div>
)};

NavBar.propTypes = {
    onChange: PropTypes.func,
    onDeselect: PropTypes.func
};

export default withStyles(styles)(NavBar);

Upvotes: 0

Views: 256

Answers (1)

Alexander Staroselsky
Alexander Staroselsky

Reputation: 38757

With React Router 4.x, try changing your import to something like the following to import a higher-level router such as BrowserRouter. This example is using an alias Router to refer to the named import BrowserRouter, but it's not necessary, you could just use BrowserRouter without the alias:

import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';

Technically you can import Router, but that would be from react-router, not react-router-dom and you would usually separately create a history object for it:

import { Router } from 'react-router';

That being said, you are most likely looking for BrowserRouter from react-router-dom, but there are other options such as HashRouter.

Updated

Regarding the NavBar component. You are also trying to import Router from react-router-dom and use Router in it's markup. First you would need to remove that import and Router, as it's not needed. If the goal is to use material-ui Tabs/Tab as navigation, you would need to use Link components instead of <a> elements for the TabLink component.

import { Link } from 'react-router-dom';

// ...

const TabLink = linkProps => (
  <Link {...linkProps}>{linkProps.linklabel}</Link>
);

Here is a StackBlitz demonstrating the functionality at a basic level.

Hopefully that helps!

Upvotes: 3

Related Questions