<PrivateRoute> with changed path not working

Viewed 48

I want to extend <Route> component of react-router-dom so it would prepend some value before path property. It would look like this:

export default function MyRoute({path, ...rest}) {
    const newpath = '/app' + path;
    return <Route path={newpath} {...rest} />
}

I want to use it like:

<MyRoute path="/login" component={Login} />

So behind the scenes it should render:

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

When I go to /app/login url it doesn't load. <Login /> still shows up only on /login.

What am I doing wrong here?

Edit

It doesn't work when used directly inside <Switch>:

<Switch>
    <MyRoute path="/login" />
</Switch>

But works when moved to another component:

<Switch>
    <Routes />
</Switch>

and Routes beeing:

<>
    <MyRoute path="/login" />
</>
1 Answers

I ended up using following code:

index.html

<!DOCTYPE html>
<html lang="pl">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    
    <!-- Below we can set subpage containing React app -->
    <script>window.react_app_url = '/my-app-page'</script>
    
    <div id="root"></div>
  </body>
</html>

Custom <MyRoute> is supposed to override all path attributes to include react_app_url defined in index.html. Ex. <MyRoute path="/home" /> should change into <Route path="/my-app-page/home" />.

MyRoute.js

import React from 'react';

export default function MyRoute({path, ...rest}) {
    let appUrl = '';
    if(window.hasOwnProperty('react_app_url')) {
        appUrl = window.react_app_url;
    }

    if( Array.isArray(path) ) {
        const paths = path.map(singlepath=>`${appUrl}${singlepath}`);
        path = paths;
    } else {
        path = appUrl + path;
    }
    return <Route path={path} {...rest} />;
}

In App.js we can now use custom <Routes> inside <Switch> and all paths will be replaced from, ex. /home to /my-app-page/home.

App.js

import React from 'react';

import {BrowserRouter, Switch} from 'react-router-dom';
import MyRoute from './MyRoute';

export default function App() {
    return (
        <BrowserRouter>
            <Switch>
                <>
                    <MyRoute path="/home" component={Home} />
                    <MyRoute path="/about" component={About} />
                    <MyRoute path="/contact" component={Contact} />
                </>
            </Switch>
        </BrowserRouter>
    );
}
Related