Why wouldn't React Router work with <Switch>?

Viewed 37

I'm learning React router, tried to build a pretty basic application like this Home.js:

import React from 'react';
import About from '../pages/About';
import { HashRouter as Router, Switch, Route, Link } from "react-router-dom";

const Navbar = () => {

    return (
        <Router>
            <div>
                <nav>
                    <ul>
                        <li>
                            <Link to="/">HOME</Link>
                        </li>
                        <li>
                            <Link to="/about-us">ABOUT US</Link>
                        </li>
                    </ul>
                </nav>
                <Switch>
                    <Route path="/about-us">
                        <About />
                    </Route>
                    <Route path="/">
                        <Home />
                    </Route>
                </Switch>
            </div>
        </Router>
    )
}

const Home = () => {
    return (
        <>
            <Navbar />
        </>
    )
}

export default Home;

Then in index.js render Home page:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Home from './pages/Home';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <Home />
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();

Problem is, Home wouldn't render in localhost:3000, terminal showed Compiled successfully! but when loading localhost:3000, it just spins forever with nothing rendered. However, if I remove the element it rendered. Folder structure set like this:

src
--pages
----About.js
----Home.js
index.js

Can anyone help?

1 Answers

You've created yourself an infinite loop from what it looks like. Your index.js returns your Home component, which then returns the Navbar, which has a router, which then returns the Home component, which then repeats that cycle over and over again.

This is the approach I would take, which will show the Navbar on both the about and home page, and will only show one of the pages at a time based on the current route.

// Navbar.js

const Navbar = () => {
    return (
        <nav>
            <ul>
                <li>
                    <Link to="/">HOME</Link>
                </li>
                <li>
                    <Link to="/about-us">ABOUT US</Link>
                </li>
            </ul>
        </nav>
    )
}

export default Navbar;
// Layout.js

import React from 'react';
import Navbar from './Navbar';
import About from '../pages/About';
import Home from '../pages/Home';
import { HashRouter as Router, Switch, Route, Link } from "react-router-dom";

const Layout = () => {
    return (
        <Router>
            <Navbar />

            <Switch>
                <Route path="/about-us">
                    <About />
                </Route>
                <Route path="/">
                    <Home />
                </Route>
            </Switch>
        </Router>
    )
}

export default Layout;
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Layout from './components/Layout';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <Layout />
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();
src
--components
----Navbar.js
----Layout.js
--pages
----About.js
----Home.js
index.js
Related