MERN App: React's Router Issue upon Rendering

Viewed 46

Problem Summary

I am working on a MERN app.

So far I have built the backend, and just starting adding routes in the frontend.

After the process of adding routes to the frontend, an issue arose. The issue is that nothing shows up on the screen. In the Console, the following error shows:

enter image description here

Problem Details

Directory Snapshot

The directory where my app is looks like this: enter image description here

App.js

// import bootstrap
import "bootstrap/dist/css/bootstrap.min.css";
// import Routers
import {BrowserRouter as Router, Route} from "react-router-dom";

import Navbar from "./components/navbar.component";
import ExerciseList from "./components/exercises-list.component";
import EditExercise from "./components/edit-exercise.component";
import CreateExercise from "./components/create-exercise.component";
import CreateUser from "./components/create-user.component";


function App() {
  return (
    <Router>
      
      <Navbar/>
      <br/>
      
      <Route exact path="/" component={ExerciseList}/>
      <Route path="/edit/:id" component={EditExercise}/>
      <Route path="/create" component={CreateExercise}/>
      <Route path="/user" component={CreateUser}/>

    </Router>

  );
}

export default App;

package.json

{
  "name": "exercise-tracker",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "bootstrap": "^5.1.3",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

navbar.component.js

import React, {Component} from 'react'
import { Link } from 'react-router-dom';

export default class Navbar extends Component {
    render() {
        return (
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <Link to="/" className="navbar-brand">Exercise Tracker</Link>
                <div className='collapse navbar-collapse'>
                    <ul className="navbar-nav mr-auto">
                        <li className="navbar-item"><Link to="/" className="nav-link">Exercises</Link></li>
                        <li className="navbar-item"><Link to="/create" className="nav-link">Create Exercise Log</Link></li>
                        <li className="navbar-item"><Link to="/user" className="nav-link">Create User</Link></li>
                    </ul>
                </div>
            </nav>
        )


    }
}

What I have tried

I tried following the steps on the console and wrapping in a in App.js (I also update App.js's line import {BrowserRouter as Router, Route} from "react-router-dom" to import {BrowserRouter as Router, Route, Routes} from "react-router-dom").

This solves the problem of the white page and the console errors. However, I do not see anything in the body (which is what I expect upon clicking the links in the navbar) and I see the following errors in the console: enter image description here At this point I did not know where to go.

1 Answers

In react-router-dom@6 the Route components can only be rendered by the Routes component or other Route components. The Route component API also changed significantly from v6, they render their content on a single element prop taking a ReactNode, a.k.a. JSX, value.

  1. Wrap the Route components in a Routes component.
  2. Render the routed components on the Route components' element prop as JSX

Example:

// import Routers
import {BrowserRouter as Router, Routes, Route} from "react-router-dom";

import Navbar from "./components/navbar.component";
import ExerciseList from "./components/exercises-list.component";
import EditExercise from "./components/edit-exercise.component";
import CreateExercise from "./components/create-exercise.component";
import CreateUser from "./components/create-user.component";

function App() {
  return (
    <Router>
      <Navbar/>
      <br/>
      <Routes>
        <Route path="/" element={<ExerciseList />} />
        <Route path="/edit/:id" element={<EditExercise />} />
        <Route path="/create" element={<CreateExercise />} />
        <Route path="/user" element={<CreateUser />} />
      </Routes>
    </Router>

  );
}

See the Migrating from v5 guide for further breaking changes in v6.

Related