Home > Mobile >  React router v6 routing issue
React router v6 routing issue

Time:04-25

I am trying to create a spring boot application with react code inside it.I have my App.js like this.Only the default route is working and other routes are not working.

import './App.css';
import React from 'react';

import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
import "react-datepicker/dist/react-datepicker.css";
import 'react-js-dialog-box/dist/index.css';
import {BrowserRouter, BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import UploadData from './UploadData';
import RoutesOfApplication from './RoutesOfApplication';
import '@szhsin/react-menu/dist/index.css';
import '@szhsin/react-menu/dist/transitions/slide.css';
//const rootElement = document.getElementById("root");

class App extends React.Component {
    render(){
    console.log('In App');
        return(
            
    <BrowserRouter>
      <Routes>
      
        <Route path="/" element={<RoutesOfApplication/>} />
        <Route path="/*" element={<RoutesOfApplication/>} />
        <Route path="/UploadData" element={<UploadData/>}/>
        <Route path="/:id" element={<UploadData/>}/>
      </Routes>
    </BrowserRouter>
        );
    }   

}
export default App;


package.json : "react-dom": "^17.0.2",
    "react": "^17.0.2",
    "react-router-dom": "^6.3.0"

Am i missing something.

CodePudding user response:

It's possible that the path = "/*" on the 2nd path line may be causing the issue. If React went in order of routing, then that "/*" would be catching all of the routes and not processing /UploadData.

If this doesn't work, I noticed that you imported BrowserRouter twice from "react-router-dom", maybe delete the second time you imported it as an alias "BrowserRouter as Router"?

Hope this works!

if you changed the ordering or removed that path, does it work?

CodePudding user response:

The problem here is you have a wildcard path "/*" and a dynamic path "/:id" in the same route.

The "/:id" route is a dynamic route, so react router doesn't care if its an a actual 32 bit unique id, or the word "hello". Therefore, it is a wildcard route ("/*") as well, but with the added functionality of providing you with a parameter called id when using the useParams hook.

In your example, since all the routes are at the same level, the wildcard route will always win due to higher specificity (since it matches itself, the root path "/",/UploadData and "/:id"). "/UploadData" can only match itself, "/:id", and /* so it will always have lower specificity.

To remedy this, use relative routing by nesting routes inside routes, and use an index route to match whenever the children don't, instead of a wildcard. Below is an example.

    <BrowserRouter>
      <Routes>
        <Route path="/" element={<RoutesOfApplication/>} >
           <Route path="UploadData" element={<UploadData/>}/>
           <Route path=":id" element={<UploadData/>}/>
           <Route index element = {<RoutesOfApplication/>} />
        </Route>
      </Routes>
    </BrowserRouter>

This way, on "/", "/UploadData", and "/:id" the right route is applied, and all our routes are covered with the appropriate logic.

You can read more here on how react router version 6 chooses the right route and how to structure them

CodePudding user response:

With your current setup the problem is between the specificity of /:id route and /* route.

    <BrowserRouter>
      <Routes>
        <Route path="/" element={<h1/>Root Route</h1>} />
        <Route path="/*" element={<h1>Catch All Route</h1>} />
        <Route path="/UploadData" element={<h1>Upload Data Route</h1>} />
        <Route path="/:id" element={<h1>Id Route</h1>} />
      </Routes>
    </BrowserRouter>
  • / resolves to the path="/" route, which is desired.
  • /UploadData resolves to the path="/UploadData" route, which is also desired. Note: Although /UploadData matches with /:id and /* paths as well but because path /UploadData is the more specific to others, react router resolves to this.
  • /1234 resolves to the path="/:id" route because it's more specific compared to /*.
  • /foo/bar resolves to path="/*" route.

NOTE: Order of routes is not important with the React Router V6, it's the specificity of the matching paths.

I guess the expectation is that /foo should resolve to the path="/*" route but in reality it would resolve to /:id route because React Router doesn't know what your IDs are.

One workaround is that inside the element for the id route you can check if the id is valid and if not you can programmatically redirect to a route that would match the catchall like /id/notfound.

A more conventional approach would be change the structure of the route, ideally it's very rare to have path params on the root, you can turn the id route into something like id/:id.

  • Related