0

I am new to react, I am got stuck with the use of react router links, I don't know what I am doing wrong, hopefully I might get answer here.

I have developed screen, which has a appbar and a drawer which open on click of an icon present in the appbar. this part is working fine. On drawer, I have three links, on click of each link, I want to load other screen on right side of drawer menu. I tried to do it by using react routes here but I got stuck with issues like: You should not use Link outside a Router - Stack Overflow,

I tried to understand answers mentioned for below issue on stackoverflow but was not able to get it correctly. Can you help me how can I use link in ListItems

Below is my code:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from 'rmwc/Theme';

import AppBar from './components/AppBar';
import DrawerMenu from './components/DrawerMenu';

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


const routes = [
  {
    path: "/",
    exact: true,
    sidebar: () => <div>home!</div>,
    main: () => <h2>Home</h2>
  },
  {
    path: "/s",
    exact: true,
    sidebar: () => <div>home!</div>,
    main: () => <h2>Home</h2>
  },
  {
    path: "/aa",
    sidebar: () => <div>bubblegum!</div>,
    main: () => <h2>Bubblegum</h2>
  },
  {
    path: "/bb",
    sidebar: () => <div>shoelaces!</div>,
    main: () => <h2>Shoelaces</h2>
  }
];


class MainComponent extends React.Component {

    constructor() {
        super();
        this.state = {
            openNow: false
        }
    }

    toggle = () => {
        const openNow = this.state.openNow;
        this.setState({
            openNow: !openNow
        });
    }

    render() {
        return (
            <ThemeProvider options={{
              primary: '#5d1049',
              secondary: '#fa3336',
              error: '#b00020',
              background: '#fff',
              surface: '#fff',
              onPrimary: 'rgba(255, 255, 255, 1)',
              onSecondary: 'rgba(255, 255, 255, 1)',
              onSurface: 'rgba(0, 0, 0, 0.87)',
              onError: '#fff',
              textPrimaryOnBackground: 'rgba(0, 0, 0, 0.87)',
              textSecondaryOnBackground: 'rgba(0, 0, 0, 0.54)',
              textHintOnBackground: 'rgba(0, 0, 0, 0.38)',
              textDisabledOnBackground: 'rgba(0, 0, 0, 0.38)',
              textIconOnBackground: 'rgba(0, 0, 0, 0.38)',
              textPrimaryOnLight: 'rgba(0, 0, 0, 0.87)',
              textSecondaryOnLight: 'rgba(0, 0, 0, 0.54)',
              textHintOnLight: 'rgba(0, 0, 0, 0.38)',
              textDisabledOnLight: 'rgba(0, 0, 0, 0.38)',
              textIconOnLight: 'rgba(0, 0, 0, 0.38)',
              textPrimaryOnDark: 'white',
              textSecondaryOnDark: 'rgba(255, 255, 255, 0.7)',
              textHintOnDark: 'rgba(255, 255, 255, 0.5)',
              textDisabledOnDark: 'rgba(255, 255, 255, 0.5)',
              textIconOnDark: 'rgba(255, 255, 255, 0.5)'
            }}>

            <Router>
                <div>
                 {routes.map((route, index) => (
                   <Route key={index} path={route.path} exact={route.exact}
                          component={route.sidebar}
                        />            
                 ))}
                </div>
            </Router>
            <AppBar toggle={this.toggle}/>
            <DrawerMenu openNow = {this.state.openNow} />

            </ThemeProvider >
            )
    }
}

ReactDOM.render(<MainComponent />, document.getElementById('root'))

AppBar.js

import React from 'react';
import ReactDOM from 'react-dom';
import '@material/top-app-bar/dist/mdc.top-app-bar.css';

import {
  TopAppBar,
  TopAppBarRow,
  TopAppBarSection,
  TopAppBarNavigationIcon,
  TopAppBarActionItem,
  TopAppBarTitle,
  SimpleTopAppBar,
  TopAppBarFixedAdjust
} from '@rmwc/top-app-bar';


class AppBar extends React.Component {
    render() {
        return (<div>
                <TopAppBar fixed={true}>
                  <TopAppBarRow>
                    <TopAppBarSection alignStart>
                        <TopAppBarNavigationIcon data-qa="navigationMenu" icon="menu" onClick = {()=>this.props.toggle()}/>
                        <TopAppBarTitle>Workforce</TopAppBarTitle>
                    </TopAppBarSection> 
                  </TopAppBarRow>
                </TopAppBar>
                <TopAppBarFixedAdjust/>
                </div>
               )
    }
}

export default AppBar;

DrawerMenu.js

import React from 'react';
import '@material/drawer/dist/mdc.drawer.css';
import '@material/list/dist/mdc.list.css';
import '../index.css'
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

import {
  Drawer,
  DrawerHeader,
  DrawerContent,
  DrawerTitle,
  DrawerSubtitle
} from '@rmwc/drawer';


import {
  List,
  ListItem,
  ListItemPrimaryText
 } from '@rmwc/list';


class DrawerMenu extends React.Component {

  handleNavClick(path) {

  }

  render() {
    return (
      <Drawer dismissible open = {this.props.openNow} >
        <DrawerHeader>
          <DrawerTitle>Team</DrawerTitle>
          <DrawerSubtitle>menu</DrawerSubtitle>
        </DrawerHeader>
        <DrawerContent>
          <List>
            <Link to='/aa'><ListItem component={Link} to="/" button />
            </Link>
            <ListItem > My Timesheet</ListItem>
            <ListItem > My Calendar</ListItem>
          </List>
        </DrawerContent>
      </Drawer>
    )
  }
}
export default DrawerMenu;

Any help will be appreciated.

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
Sagar
  • 1,115
  • 2
  • 11
  • 23

1 Answers1

1

In MainComponent you are rendering DrawerMenu outside of your Router. You are enclosing your routes in the Router tag, but all react-router Link elements must also be within a router. DrawerMenu uses Link -- thus the error.

The following:

    <Router>
        <div>
         {routes.map((route, index) => (
           <Route key={index} path={route.path} exact={route.exact}
                  component={route.sidebar}
                />            
         ))}
        </div>
    </Router>
    <AppBar toggle={this.toggle}/>
    <DrawerMenu openNow = {this.state.openNow} />

should instead be:

<Router>
    <>
       <div>
        {routes.map((route, index) => (
          <Route key={index} path={route.path} exact={route.exact}
              component={route.sidebar}
            />            
        ))}
       </div>
       <AppBar toggle={this.toggle}/>
       <DrawerMenu openNow = {this.state.openNow} />
    </>
</Router>
Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198