React routing within another component V6

2.2k views Asked by At

Im using Reavt V6 route.

Im struggeling to get my routes inside gamecomponent to work.

visiting /test results in a completly blank page. while it should load crime module within gamecomponent. visiting / renders gamecomponent, but /test does not render gamecomponent and the route within that.

How do i make this to work?

visiting url /crime should result in gamecomponent beeing loaded, and that

<Route path="/test" element={<Crime />} />

should be loaded.

app.js

import React from 'react';
import logo from './logo.svg';
import './App.css';
import GameComponent from './gameComponent.jsx';
import { BrowserRouter as Router } from 'react-router-dom';
import { Routes, Route, Navigate, Outlet, Switch } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import Login from './components/login/login.jsx';



function App() {
    
  return (

  <Router>
    <Routes>
       <Route path="/login" element={<Login />} />
       <PrivateRoute  isAuth={true} path="/" component={GameComponent}  redirectTo='/login'/>
    </Routes>
  </Router>
  );
}
export default App;

privateroute:

import React from 'react';
import PropTypes from 'prop-types';
import { Route, Navigate } from 'react-router-dom';
import { useNavigate  } from "react-router-dom";
import Login from './components/login/login.jsx';
import GameComponent from './gameComponent.jsx';


const PrivateRoute = ({ component: Component, redirectTo, isAuth, path, ...props }) => {
    //isAuth = false;
    
    if(!isAuth) {
        return <Navigate to={redirectTo} />;
    }
    return <Route path={path} element={<Component />} />
};

export default PrivateRoute;

gamecomponent:

import React, {Component} from 'react';
//import Component from 'react-dom';
import SideBarRight from './components/game/sideBarRight.jsx';
import SideBarLeft from './components/game/sideBarLeft.jsx';
import Crime from './components/game/crime.jsx';
import Login from './components/login/login.jsx';
import './gameComponent.css';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import { BrowserRouter} from "react-router-dom";


class GameComponent extends Component{
 constructor() {
    super();
    this.state = {
    userData: {
        user: {cash:0, bank:0, weapon:'', username: 'test', locationname: 'Bankok',
        defence: 0},
        rankbar: {rankpercent: 50, rank: 'Mafia'},
        }
    }
    
    
    
    
  }


render() {
    return (
    <div className="main">
    <div className="sidebar left">
                <SideBarLeft/>

    </div>
    <div className="middleContentHolder">
     <Route path="/" element={<Crime />} />
    <Route path="/test" element={<Crime />} />
    <Route path="/crime" element={<Crime />} />
    <Route path="/test2" element={<SideBarRight UserData={this.state.userData} />} />


        <div className="col-8">
            <div className="content">
            <div className="header"><span>Test...</span></div>
            
            </div>
        </div>
    </div>
    <div className="sidebar right">
        <SideBarRight UserData={this.state.userData}/>
        </div>
    </div>
    );
  }
    
}



export default GameComponent;
2

There are 2 answers

6
Luis Paulo Pinto On BEST ANSWER

According to React Router documents:

You can render a element anywhere you need one, including deep within the component tree of another . These will work just the same as any other , except they will automatically build on the path of the route that rendered them. If you do this, make sure to put a * at the end of the parent route's path. Otherwise the parent route won't match the URL when it is longer than the parent route's path, and your descendant won't ever show up.

You can read more about it here - Descendant Routes

So, you just need to do 2 little changes:

app.js

Add * to yout path in PrivateRoute:

<Routes>
   <Route path="/login" element={<Login />} />
   <PrivateRoute
      isAuth={true}
      // Here's the trick
      path="/*"
      component={GameComponent}
      redirectTo="/login"
   />
</Routes>

gamecomponent.jsx

Wrapper Route with <Routes>:

<Routes>
   <Route path="/" element={<Crime />} />
   <Route path="/test" element={<Crime />} />
   <Route path="/crime" element={<Crime />} />
   <Route
      path="/test2"
      element={<SideBarRight UserData={this.state.userData} />}
    />
</Routes>

HereĀ“s a code sample: codesandbox

You can check it with routes:

/ => show crime component

/crime => show crime component

/anticrime => show antcrime component

5
rleiva93 On

Instead of element={<Crime />} you should use: component={Crime}.

Check the documentation for reference.

In your PrivateRoute component, you might want to enhance it using the <Redirect> component.

Please refer to the answer to this question, even has a post with a very good explanation that might help you.