Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding routes inside a component in react router dom version 6

I am trying to migrate from react router 5 to react router 6. I coded a simple frontend where only if the login button is clicked you can go to the profile page. and inside profile page there are two links to view profile and edit profile.

//App.js
import './App.css';

import Header from './components/Header';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import Profile from './pages/Profile';
import NotFoundPage from './pages/NotFoundPage';
import Post from './pages/Post';
import GroupProfile from './pages/GroupProfile';

import {BrowserRouter as Router, Routes, Route, Navigate} from 'react-router-dom';
import {useState} from 'react';

function App(){
    const [login, setLogin] = useState(false);
    const [glogin, setGlogin] = useState(false);
    return(
        <div className="App">
            <Router>
                <Header />
                <button onClick={() => setLogin(!login)}> {!login?"Login":"Logout"} </button>
                <span> | </span>
                <button onClick={() => setGlogin(!glogin)}> {!glogin?"GroupLogin":"GroupLogout"} </button>
                <Routes>
                    <Route path='/' element={<HomePage />} />
                    <Route path='/about' element={<AboutPage />} />
                    {/*<Route path='/prof'>
                        {login ? <Profile />:<Navigate to='/' />}  Nope, in react_router_dom6 putting other things rather than function that returns pages are not valid
                    </Route>*/}
                    <Route path='/group' element={<GroupProfile g_login={glogin} />} />
                    <Route path='/prof/*' element={<Profile l_ogin={login} />} />
                        

                    <Route path='/post/:id' element={<Post />} />
                    <Route path='*' element={<NotFoundPage />} />

                </Routes>
            </Router>
        </div>
    )
}

export default App;

And these are groupprofile page and profile page.

GroupProfile.js

import React from 'react';
import {useEffect} from 'react';
import {useNavigate} from 'react-router-dom';

function GroupProfile({ g_login }){
    let nav = useNavigate();
    useEffect(() => {
        if (!g_login) {
            nav("/");
        }
    },[g_login, nav])  //you know useEffect hook, if dependancy list is given, when they change then hook will be triggered.

    return(
        <div>
            <p>This is the GroupProfile</p>
        </div>
    )
}

export default GroupProfile;

Profile.js

import React, {useEffect} from 'react';
import {Route, Routes, useRouteMatch, Link, useNavigate, useLocation} from 'react-router-dom';

import EditProfile from '../components/EditProfile';
import ViewProfile from '../components/ViewProfile';

/*
function Profile(){
    const { path, url } = useRouteMatch();
    //console.log(useRouteMatch());

    return(
        <>
            <h3>Profile Page</h3>
            <ul>
                <li><Link to={`${url}/viewprofile`}>View Profile</Link></li>
                <li><Link to={`${url}/editprofile`}>Edit Profile</Link></li>
            </ul>
            <Route path={`${path}/viewprofile`} component={ViewProfile} />
            <Route path={`${path}/editprofile`} component={EditProfile} />
        </>
    )
}
*/
function Profile({l_ogin}){
    let nav = useNavigate();
    let location = useLocation();
    //console.log(location)
    useEffect(() => {
        if (!l_ogin) {
            nav("/");
        }
    },[l_ogin, nav])  //you know useEffect hook, if dependancy list is given, when they change then hook will be triggered.
    return(
        <div>
            <h1>Congrats! you made it to the profile page mate...</h1>
            <ul>
                <li><Link to={`${location}/viewprofile`}>View Profile</Link></li>
                <li><Link to={`${location}/editprofile`}>Edit Profile</Link></li>
            </ul>
            <Routes>

                <Route path={`${location}/viewprofile`} element={<ViewProfile />} />
                <Route path={`${location}/Editprofile`} element={<EditProfile />} />
            </Routes>
        </div>
    )
}

export default Profile;

I have commented the Profile component that works in react router version 5 and it is supposed to navigate to /prof/viewprofile when View Profile link is clicked. ViewProfile.js and EditProfile.js are simple components

ViewProfile.js

import React from "react";

const ViewProfile = () => {
    return(
        <div>
            <h3><i>This is what you have to see in the profile.</i></h3>
        </div>
    )
}

export default ViewProfile;

The code I used in react router 5 works fine and when I clicked View Profile it navigates to /prof/viewprofile without any problem. But when I use react router 6 it doesn't navigate to /prof/viewprofile and it just stays in the /prof, but url changes to something like /prof/[object%20Object]/viewprofile. Can someone show me what am I doing wrong here?

like image 474
d0ppL3G Avatar asked Oct 16 '25 13:10

d0ppL3G


2 Answers

location is an object, and if this is what you were trying to use you'd need location.pathname, but this is not what you want to try and use to build paths for descendent routes. When rendering Routes components and descendent routes, the routes are already built relative to the parent route. There is no need to try and build/implement the relative-ness yourself.

Example:

function Profile({ l_ogin }){
  const navigate = useNavigate();

  useEffect(() => {
    if (!l_ogin) {
      navigate("/", { replace: true });
    }
  }, [l_ogin, navigate]);

  return(
    <div>
      <h1>Congrats! you made it to the profile page mate...</h1>
      <ul>
        <li><Link to="viewprofile">View Profile</Link></li>
        <li><Link to="editprofile">Edit Profile</Link></li>
      </ul>
      <Routes>
        <Route path="viewprofile" element={<ViewProfile />} />
        <Route path="editprofile" element={<EditProfile />} />
      </Routes>
    </div>
  );
}

If you wanted to keep the first route implementation you were trying to use then this is the correct syntax. You still need to render the routed content on the element prop.

<Route
  path='/prof'
  element={login ? <Profile /> : <Navigate to='/' replace />}
/>
like image 111
Drew Reese Avatar answered Oct 18 '25 07:10

Drew Reese


I realize these are the docs for v5: https://v5.reactrouter.com/web/api/Hooks/uselocation

But I suspect that before you didn't use the useLocation() hook by default?

From the url that gets parsed you can tell that the location variable not a string but an object [object%20Object]

Could you try: ${location.pathname} where you now have ${location} ?

like image 37
Jelmer Avatar answered Oct 18 '25 07:10

Jelmer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!