skip to Main Content

I have the below code. It exists in a file that has the route "login". From root, I have another route, "create-account".
Whenever I click on this "a" element in Login.jsx to bring me to "create-account", it takes me to "login/create-account" instead. I’ve also tried "./create-account" and "../create-account".
Is there anything I can do? I can’t find any solutions.
I am using React-Router-Dom 6.9.0.

Login.jsx

import { useNavigate } from "react-router-dom";

export default function LoginForm() {
  const navigate = useNavigate();

  return (
    <div className="loginForm">

      <h1>Login</h1>
      <p>
        Don't have an account? 
        <a onClick={() => navigate("../create-account")}> Create an account </a>.
      </p>

And my App.jsx (which is serving as my Router)

import React, { useState, createContext } from 'react'
import { Routes, Route } from 'react-router-dom'
import { BrowserRouter as Router } from 'react-router-dom'
import { useCookies } from 'react-cookie'

import Master from './Master.jsx'
import HomePage from './HomePage.jsx'
import DashCards from './DashCards.jsx'
// Authentication Pages
import LoginForm from './Auth/SignInForm.jsx'
//import CreateAccountForm from './Auth/CreateAccount.jsx'
//import LogoutPage from './Auth/SignOut.jsx'

export const AppContext = createContext()

export default function App() {

  const [cookies, setCookie, removeCookie] = useCookies(['token'])
  let [authenticated, setAuthenticated] = useState(cookies.token !== undefined)
  let [loggedInUser, setLoggedInUser] = useState([])
  let [users, setUsers] = useState([])

  return (
    <AppContext.Provider value={{ authenticated, setAuthenticated, loggedInUser, setLoggedInUser, setCookie, removeCookie, users, setUsers, }}>
      <Router className="react-stuff">
        <Routes>

          <Route path="/" element={<Master/>} >
            <Route index element={<HomePage />} />

            <Route path="login" element={<LoginForm />} />
            {/* <Route path="logout" element={<LogoutPage />} /> */}
            <Route path="create-account" element={<div>404: Page Under Construction</div>} />
          </Route>

        </Routes>
      </Router>
    </AppContext.Provider >
  )
}

2

Answers


  1. In your case, since Login.jsx is nested under the login route, using "../create-account" would navigate up one level from login to the root, then navigate to create-account, resulting in login/create-account.

    To navigate to the create-account route directly from login, you need to specify the absolute path from the root:

    <a onClick={() => navigate("/create-account")}>Create an account</a>

    This way, it will navigate directly to the create-account route regardless of the current route’s nesting level.

    Your Login.jsx would look like this:

    import { useNavigate } from "react-router-dom";
    
    export default function LoginForm() {
      const navigate = useNavigate();
    
      return (
        <div className="loginForm">
          <h1>Login</h1>
          <p>
            Don't have an account? 
            <a onClick={() => navigate("/create-account")}>Create an account</a>.
          </p>
        </div>
      );
    }

    app.jsx

    import React, { useState, createContext } from 'react';
    import { Routes, Route } from 'react-router-dom';
    import { BrowserRouter as Router } from 'react-router-dom';
    import { useCookies } from 'react-cookie';
    
    import Master from './Master.jsx';
    import HomePage from './HomePage.jsx';
    import DashCards from './DashCards.jsx';
    // Authentication Pages
    import LoginForm from './Auth/SignInForm.jsx';
    //import CreateAccountForm from './Auth/CreateAccount.jsx';
    //import LogoutPage from './Auth/SignOut.jsx';
    
    export const AppContext = createContext();
    
    export default function App() {
    
      const [cookies, setCookie, removeCookie] = useCookies(['token']);
      let [authenticated, setAuthenticated] = useState(cookies.token !== undefined);
      let [loggedInUser, setLoggedInUser] = useState([]);
      let [users, setUsers] = useState([]);
    
      return (
        <AppContext.Provider value={{ authenticated, setAuthenticated, loggedInUser, setLoggedInUser, setCookie, removeCookie, users, setUsers }}>
          <Router className="react-stuff">
            <Routes>
              <Route path="/" element={<Master/>}>
                <Route index element={<HomePage />} />
                <Route path="login" element={<LoginForm />} />
                {/* <Route path="logout" element={<LogoutPage />} /> */}
                <Route path="create-account" element={<div>404: Page Under Construction</div>} />
              </Route>
            </Routes>
          </Router>
        </AppContext.Provider>
      );
    }
    Login or Signup to reply.
  2. If you are using raw anchor tags then you’ll want to prevent the default action.

    <a
      onClick={(e) => {
        e.preventDefault();
        navigate("../create-account");
      }}
    >
      Create an account
    </a>
    

    It would be better to just render a Link component though which will already correctly handle this behavior. You’ll need only provide the target path you want to navigate to.

    import { Link } from 'react-router-dom';
    
    ...
    
    <Link to="../create-account">
      Create an account
    </Link>
    

    Depending where this LoginForm is being rendered, using the relative path "../create-account" may not be correct. If all you need to do is navigate to "/create-account" then just use the absolute path instead.

    <Link to="/create-account">
      Create an account
    </Link>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search