2

I have recently started developing frontend apps with React and I come from a little programming experience with react-native. To improve my knowledge on react I studied both the official documentation and took courses on udemy. So I'm building a small test app in which to use react routing (following what we saw in the udemy course). However, I have the following error related to routing (I attach the error screen)

enter image description here

I have searched here on the stack that online for possible solutions, such as downgrading react-router-dom, or modifying the history declaration, but unfortunately I still get this error and I can't understand what it comes from. Do you have any suggestions or advice?

My app configuration:

  • package.json

  "name": "app1",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@reduxjs/toolkit": "^1.8.1",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^12.1.4",
    "@testing-library/user-event": "^13.5.0",
    "history": "^5.3.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-redux": "^7.2.8",
    "react-router": "^6.3.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.0",
    "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"
    ]
  }
}

  • routes.js
import React, { Component } from 'react';

import Component1 from './functional/component1';
import Component2 from './functional/component2';
import Component3 from './functional/component3';

//import container home-page
import Container1 from './containers/container1';
import Header from './containers/header';
import history from './utils/history';

//react router import
import { Router, Route } from 'react-router';

class Routes extends Component {
   render() {
      return (
         <div>
            <Router history={history.location} navigator={history} >
               <div>
                  <Header />
                  <Route path="/" component={Container1} />
                  <Route path="/component1" component={Component1} />
                  <Route path="/component2" component={Component2} />
                  <Route path="/component3" component={Component3} />
               </div>
            </Router>
         </div>
      )
   }
}

export default Routes;

-history.js

var createHistory = require('history').createBrowserHistory;
export default createHistory();
2
  • 1
    You're supposed to use BrowserRouter (use import { BrowserRouter as Router, Route } from 'react-router'; instead), also there's no need for the history package, react-router manages its own history. My recommendation in general would be to use the official tutorial, not some possibly outdated course elsewhere. reactrouter.com/docs/en/v6/getting-started/tutorial Commented Apr 6, 2022 at 12:19
  • @ChrisG thank's now i've more clear the behavior of react navigation, i will try to migrate from the course navigation to react-6 navigation like the official docs Commented Apr 6, 2022 at 12:37

2 Answers 2

1

Issue

The low-level Router takes a few different props than it did in v5.

Router

declare function Router(
  props: RouterProps
): React.ReactElement | null;

interface RouterProps {
  basename?: string;
  children?: React.ReactNode;
  location: Partial<Location> | string; // <-- required
  navigationType?: NavigationType;
  navigator: Navigator;                 // <-- required
  static?: boolean;
}

Router source

export function Router({
  basename: basenameProp = "/",
  children = null,
  location: locationProp, // <-- undefined location
  navigationType = NavigationType.Pop,
  navigator,
  static: staticProp = false,
}: RouterProps): React.ReactElement | null {
  ...

  let {
    pathname = "/", // <-- cannot read "pathname" of undefined!
    search = "",
    hash = "",
    state = null,
    key = "default",
  } = locationProp;

  ...

  if (location == null) {
    return null;
  }

  return (
    <NavigationContext.Provider value={navigationContext}>
      <LocationContext.Provider
        children={children}
        value={{ location, navigationType }}
      />
    </NavigationContext.Provider>
  );
}

You are incorrectly using a history prop instead of the location prop, and this is why location is undefined in the component and unable to read a pathname.

Additionally, in react-router-dom@6 the Route components necessarily need to be wrapped in the Routes component in order for route path matching and rendering to work.

Solution

Pass the correct required props and wrap the Route components in Routes component.

import React, { Component } from 'react';

import Component1 from './functional/component1';
import Component2 from './functional/component2';
import Component3 from './functional/component3';

//import container home-page
import Container1 from './containers/container1';
import Header from './containers/header';
import history from './utils/history';

//react router import
import { Router, Routes, Route } from 'react-router';

class Routes extends Component {
  render() {
    return (
      <div>
        <Router location={history.location} navigator={history} >
          <div>
            <Header />
            <Routes>
              <Route path="/" component={Container1} />
              <Route path="/component1" component={Component1} />
              <Route path="/component2" component={Component2} />
              <Route path="/component3" component={Component3} />
            </Routes>
          </div>
        </Router>
      </div>
    )
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You are using react router v6 and in v6 you have to wrap all of your route's in <Routes>...</Routes> tag.

//react router import
import { Router, Route, Routes } from 'react-router'; // Make sure to import ----Routes----

class Routes extends Component {
   render() {
      return (
         <div>
            <Router history={history.location} navigator={history} >
               <div>
                  <Header />
                  <Routes>
                    <Route path="/" component={Container1} />
                    <Route path="/component1" component={Component1} />
                    <Route path="/component2" component={Component2} />
                    <Route path="/component3" component={Component3} />
                  </Routes>
               </div>
            </Router>
         </div>
      )
   }
}

export default Routes;

And you can't add anything between <Routes>...</Routes> except <Route />.

2 Comments

That's just one of several issues though.
I've modified like your code, and renamig the class from Routes to Routers otherwise i've a naming conflict, but i've the same problem

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.