Reputation: 1609
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
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