Search code examples
javascriptreactjsreact-routerreact-router-dom

Failed to use React Router v6 - Navigation from <Login /> to <Home /> with <Navigation /> does not work


I'm trying to create a simple application focused on React router. I would like that after clicking on the Login button(there will be a form for authentication in the component), the user will be redirected to the Menu page(Navigation component). In this case, it looks like I click the button, but only the URL changes. I tried to add Routes and Route component to Login component...)

<div>
    <Link to="/home" >
        Login
    </Link>
    <Routes>
        <Route path="/home" element={<Home />} />
    </Routes>
</div>

but in this case the Menu works in such a way that when I click on the Link e.g. about, the About component is not displayed. So I don't know if there is a bug somewhere between the Navigation and Login components or if I'm going about it completely wrong.

index.js

import "bootstrap/dist/css/bootstrap.css";
import React from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";

const baseUrl = document.getElementsByTagName("base")[0].getAttribute("href");
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <BrowserRouter basename={baseUrl}>
    <App />
  </BrowserRouter>
);

App.js

import React from "react";
import Login from "./components/Login";

const App = () => {
  return (
    <div>
      <Login />
    </div>
  );
};
export default App;

Login.jsx

import React from "react";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Home from "./Home";
const Login = () => {
  return (
    <div>
      <Link to="/home" style={{ padding: 5 }}>
        Login
      </Link>
    </div>
  );
};

export default Login;

I have pasted code already to codebox


Solution

  • In the sandbox only the Login component is rendered by the App component.

    If you want Login to be rendered on the root "/" route, alone without the nav menu, then these are the changes I suggest:

    1. Refactor MyOutlet to render the Navigation component and Routes and various routes. Add a route on "/" for the Login component. Create a new layout route component to render the Navigation component with an Outlet for nested routes and wrap all but the "/" route.

      import React from "react";
      import { Routes, Route, Outlet } from "react-router-dom";
      import Navigation from "../Navigation";
      import Home from "../Home";
      import About from "../About";
      import Login from "../Login";
      import NoMatch from "../ErrorView/NoMatch";
      
      const NavLayout = () => (
        <>
          <Navigation />
          <Outlet />
        </>
      );
      
      const MyOutlet = () => {
        return (
          <Routes>
            <Route path="/" element={<Login />} />
            <Route element={<NavLayout />}>
              <Route path="/home" element={<Home />} />
              <Route path="/about" element={<About />} />
              <Route path="*" element={<NoMatch />} />
            </Route>
          </Routes>
        );
      };
      
      export default MyOutlet;
      
    2. Remove Navigation from the Home component

      import React from "react";
      
      const Home = () => {
        return (
          <div>
            <div>Toto je home komponenta</div>
          </div>
        );
      };
      
      export default Home;
      
    3. Update App to render the updated MyOutlet component.

      import React from "react";
      import MyOutlet from "./components/Router/MyOutlet";
      
      const App = () => {
        return (
          <div>
            <MyOutlet />
          </div>
        );
      };
      
      export default App;
      
    4. Update the Navigation component to render just the links.

      import React from "react";
      import { Link } from "react-router-dom";
      
      const Navigation = () => {
        return (
          <div>
            <nav style={{ margin: 10 }}>
              <Link to="/" style={{ padding: 5 }}>
                Home
              </Link>
              <Link to="/about" style={{ padding: 5 }}>
                About
              </Link>
            </nav>
          </div>
        );
      };
      
      export default Navigation;
      

    Demo

    Edit failed-to-use-react-router-v6-navigation-from-login-to-home-with-navi

    enter image description here enter image description here