1

I'm struggling with creating routes using "react-router-dom". The default "Page1" is being displayed: as you can see here, but I'm getting a blank page when switching to "Page2" or "Page3".

I'll be glad if someone will be able to take a look at my code. Thanks!

App.js:

import Layout from "./Layout";
import Login from "./Login";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path={"/"} component={Layout} />
        <Route path={"/login"} component={Login} />
      </Switch>
    </Router>
  );
}

export default App;   

Login.js:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(() => ({
  root: {
    flexGrow: "1",
    height: "100%",
  },
}));

const Login = () => {
  const classes = useStyles();
  return <div className={classes.root}>Login</div>;
};

export default Login;

Layout.js:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Header from "./Header";
import Menu from "./Menu";
import Page1 from "./Page1";
import Page2 from "./Page2";
import Page3 from "./Page3";
import { Switch, Route } from "react-router-dom";

const useStyles = makeStyles(() => ({
  root: {
    display: "flex",
    overflow: "hidden",
    backgroundColor: "red",
  },
}));

export default function Layout() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <Menu />
      <Grid container direction="column">
        <Grid item xs>
          <Header />
        </Grid>
        <Grid item xs>
          <Switch>
            <Route exact path="/" component={Page1} />
            <Route path="/page2" component={Page2} />
            <Route path="/page3" component={Page3} />
          </Switch>
        </Grid>
      </Grid>
    </div>
  );
}

Menu.js

import { useHistory } from "react-router-dom";
import React, { useState } from "react";
import { makeStyles, withStyles } from "@material-ui/core/styles";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";

const useStyles = makeStyles((theme) => ({
  root: {
    height: "100vh",
    width: "90px",
    backgroundColor: theme.palette.background.menu,
    textAlign: "center",
    justifyContent: "center",
    backgroundColor: "lightblue",
  },
}));

const StyledListItem = withStyles((theme) => ({
  root: {
    flexDirection: "column",
    textAlign: "center",
    opacity: 0.8,
  },
}))(ListItem);

const MainNavMenu = (props) => {
  const [selectedIndex, setSelectedIndex] = useState(0);
  const classes = useStyles(props);
  let history = useHistory();

  // Navigate between pages
  const navigate = (text, index) => {
    setSelectedIndex(index);
    if ("page1" === text) {
      history.push("/");
    } else if ("page2" === text) {
      history.push("/page2");
    } else {
      history.push("/page3");
    }
  };

  return (
    <div className={classes.root}>
      <List>
        {["page1", "page2", "page3"].map((text, index) => (
          <StyledListItem
            button
            key={index}
            selected={selectedIndex === index}
            onClick={() => {
              navigate(text, index);
            }}
          >
            <ListItemText primary={text} />
          </StyledListItem>
        ))}
      </List>
    </div>
  );
};

export default MainNavMenu;

Page1.js (All pages look the same):

function Page1() {
  return (
    <div>
      <h1>Page 1</h1>
    </div>
  );
}

export default Page1;

4 Answers 4

2

Your app needs to know that it should handle /page2 and /page1 through the Layout component. Right now it does not because your Route only matches exact path={"/"}.

You can remove the exact to send all traffic through Layout. Since the first match is used, you always want to have your Route components listed from most specific to least specific. Without exact, the Route for Layout now belongs at the bottom of the list.

function App() {
  return (
    <Router>
      <Switch>
        <Route path={"/login"} component={Login} />
        <Route path={"/"} component={Layout} />
      </Switch>
    </Router>
  );
}

The paths in your Layout don't match up with the ones in Menu. You have no /page3 in Layout.

Layout:

<Route exact path="/" component={Page1} />
<Route path="/page1" component={Page2} />
<Route path="/page2" component={Page3} />

Menu:

{["page1", "page2", "page3"].map((text, index) => (

Likely you want to change Layout like this:

<Route exact path="/" component={Page1} />
<Route path="/page2" component={Page2} />
<Route path="/page3" component={Page3} />

I personally would do the navigation with the react-router-dom Link component but you would need to handle your styling differently.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I removed the exact and moved the default path to the bottom and it worked!
1

There is no page1 or page2 route in your code. That's why you get a blank page.

2 Comments

I forgot to add the Menu.js code and updated the paths in Layout.js and still not working
You need to put "/" before your path names. like path="/page1"
0

Remove exact in app component.Since you put exact, its not switching to nested components.

<Switch>
      <Route path={"/"} component={Layout} />
      <Route path={"/login"} component={Login} />
</Switch>

Edit to the comment

Just name the route instead of blank e.g "/home" and redirect blank route to home. Like this

<Switch>
      <Route exact path="/" > <Redirect to="/home" /> </Route>
      <Route path={"/home"} component={Layout} />
      <Route path={"/login"} component={Login} />
</Switch>

Mostly page1,page2,page3 will work. If not , implement "useRoutematch" and put paths in <Route> in Layout.js

1 Comment

Now I can navigate between "/page1" "/page2" and "/page3" but when I navigate to "/login" (by changing the url) the Login screen isn't displayed. Instead I see Layout.js with no page
0
 import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
 import React, { Fragment, useEffect } from 'react';
  <Router>
    <Fragment>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Landing} />
        <Route component={Routes} />
      </Switch>
    </Fragment>
  </Router>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.