nested path dosent work in react router dom - javascript

I am trying to create a browser router for my app but the nested paths are not working.
import React from 'react';
import './App.css';
import HomeScreen from './screens/HomeScreen';
import {
createBrowserRouter,
createRoutesFromElements,
Route,
RouterProvider
} from 'react-router-dom';
import LoginScreen from './screens/LoginScreen';
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<HomeScreen />}>
<Route path="dashboard" element={<LoginScreen />} />
{/* ... etc. */}
</Route>
)
);
function App() {
return (
<div className="App">
<RouterProvider router={router} />
</div>
);
}
export default App;
On this code both "localhost:3000/" and "localhost:3000/dashboard" are opening the HomeScreen page only.
Can you tell me what I should do to make "/dashboard" open LoginSrceen instead of HomeScreen?

If you are nesting routes then the parent route necessarily needs to render an Outlet component for nested routes to render their element content into.
Example:
import { Outlet } from 'react-router-dom';
const HomeScreen = () => {
...
return (
... Home screen UI ...
<Outlet /> // <-- nested routes render content here
...
);
};
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<HomeScreen />}>
<Route path="dashboard" element={<LoginScreen />} />
{/* ... etc. */}
</Route>
)
);
function App() {
return (
<div className="App">
<RouterProvider router={router} />
</div>
);
}
On the off-hand chance that you actually want HomeScreen and LoginScreen to render each on their own discrete routes, then they should not be nested one in the other, but instead should be rendered as sibling routes. Render HomeScreen on an index route such that it will be rendered when the URL path matches the parent route, e.g. "/".
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/">
<Route index element={<HomeScreen />} />
<Route path="dashboard" element={<LoginScreen />} />
{/* ... etc. */}
</Route>
)
);
function App() {
return (
<div className="App">
<RouterProvider router={router} />
</div>
);
}

Related

Why do we use Routes instead of Switches in React? Whereas our work is done by the switch

import React from "react";
// import { BrowserRouter as Router, Route, Switch} from "react-router-dom"
import Home from "./Home";
import Header from "./Header";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
const App = () => {
return (
//BEM
<Router>
<div className="app">
{/* Switch case */}
<Switch>
{/* checkout page */}
<Route path="/checkout" >
<Header/>
{/* Header */}
<h1>I am a Checkout, Smash the like button</h1>
</Route>
<Route path="/" >
<Header/>
<Home/>
</Route>
</Switch>
</div>
</Router>
);
};
export default App;
I am update the code with the help of Routes, but my page is gone. So what do I convert?
import React from "react";
import Home from "./Home";
import Header from "./Header";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
const App = () => {
return (
//BEM
<Router>
<div className="app">
<Routes>
{/* checkout page */}
<Route path="/checkout" element={<Header/>} >
<h1>I am a Checkout, Smash the like button</h1>
<Route path="/" element={Header/>} />
//Here I want both page link in one path Header and Home.
</Route>
</Routes>
</div>
</Router>
);
};
export default App;
From what I can understand of your question you are trying to render a common Header component with each route. For this you can render the Header component on a layout route that renders also an Outlet component for nested children routes.
Example:
import React from "react";
import Home from "./Home";
import Header from "./Header";
import { BrowserRouter as Router, Routes, Route, Outlet } from "react-router-dom";
const Layout = () => (
<>
<Header />
<Outlet />
</>
);
const App = () => {
return (
<Router>
<div className="app">
<Routes>
<Route element={<Layout />}>
{/* checkout page */}
<Route
path="/checkout"
element={<h1>I am a Checkout, Smash the like button</h1>}
/>
<Route path="/" element={<Home />} />
</Route>
</Routs>
</div>
</Router>
);
};
See nested routes in the documentation for more details.

React v6-Redux Create PrivateRoutes

Im trying to create a PrivateRoutes in addition to the regular routes.
After login, the page is successfully re-direct to /home, however when I tried to open /work, the page will go back to /home. all the data from state.valid is also shows "unidentified" in /work.
I figured it out that inside the privateRoutes it check if valid.isAuthenticated is true or not. However since. valid.isAuthenticated is set to false as initial value in reducer, everytime I open /home or /work, it re-render /login and then render /home or /work.
How do I fix to not to render /login before opening other pages?
Here is my PrivateRoutes.js
import React from "react";
import { useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
const PrivateRoute = ({ children }) => {
const valid = useSelector((state) => state.valid);
return valid.isAuthenticated ? children : <Navigate to="/login" />;
};
export default PrivateRoute;
here is my AppRouter.js
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import PrivateRoute from "./PrivateRoute";
import App from "../components/App";
import Login from "../components/Login";
import HomePage from "../components/HomePage";
import WorkPage from "../components/WorkPage";
const AppRouter = () => (
<BrowserRouter>
<div>
<NavigationBar />
<div>
<Routes>
<Route path="/" element={<App />} exact />
<Route path="/login" element={<Login />} exact />
<Route path="/home" element={<PrivateRoute><HomePage /></PrivateRoute>} />
<Route path="/work" element={<PrivateRoute><WorkPage /></PrivateRoute>} />
</Routes>
</div>
</div>
</BrowserRouter>
);
export default AppRouter;
useEffect(() => {
if (valid.isAuthenticated) {
navigate("/home");
}
},[valid.isAuthenticated]);
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import PrivateRoute from "./PrivateRoute";
import App from "../components/App";
import Login from "../components/Login";
import HomePage from "../components/HomePage";
import WorkPage from "../components/WorkPage";
const AppRouter = () => {
useEffect(() => {
if (!valid.isAuthenticated) {
navigate("/login");
}
});
return (
<BrowserRouter>
<div>
<NavigationBar />
<div>
{valid.isAuthenticated ? <>
<Routes>
<Route path="/" element={<App />} exact />
<Route path="/home" element={<HomePage />} />
<Route path="/work" element={<WorkPage />} />
</Routes>
</>
:
<>
<Routes>
<Route path="/login" element={<Login />} exact />
</Routes>
</>
}
</div>
</div>
</BrowserRouter>
)
};
export default AppRouter;

Why unable to use protectRoute inside Router in react?

I have a react application in which users can access the homepage only after login/signup.
I have used protectRoutes to implement this , however I m getting the following error inside Router component:
A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.
The code for app.js file:
import {useState} from 'react'
import './App.css';
import {Routes,Route,Link} from 'react-router-dom'
import SignupPage from './Pages/SignupPage';
import LoginPage from './Pages/LoginPage';
import Homepage from './Pages/Homepage';
import PrivateRoute from "./Pages/PrivateRoute";
import {HashRouter as Router} from 'react-router-dom'
function App() {
const [username,setUsername]=useState("");
const [currentUser,setCurrentUser]=useState({});
return (
<Router>
<div className="App">
<Route path="/" exact element={<SignupPage></SignupPage>}/>
<Route path="/signup" exact element={<SignupPage currentuser={currentUser} setcurrentuser={setCurrentUser} setusername={setUsername}></SignupPage>}/>
<Route path="/login" exact element={<LoginPage></LoginPage>}/>
<PrivateRoute path="/homepage" exact currentuser={currentUser} element={<Homepage user={currentUser} username={username} setusername={setUsername}></Homepage>}/>
</div>
</Router>
);
}
export default App;
Whats the error here and how do I fix it?
Issue
You are rendering Route components directly and are not wrapping them in a Routes component.
Solution
Refactor the PrivateRoute component to render an Outlet component instead of a Route and wrap the routes you want to protect.
Example:
import { Navigate, Outlet } from 'react-router-dom';
const PrivateRoute = ({ currentuser }) => {
// auth business logic
return isAuthenticated
? <Outlet />
: <Navigate to="/login" replace />;
};
...
import { HashRouter as Router, Routes, Route, Link} from 'react-router-dom'
function App() {
const [username,setUsername]=useState("");
const [currentUser,setCurrentUser]=useState({});
return (
<Router>
<div className="App">
<Routes>
... unprotected routes ...
<Route path="/" element={<SignupPage />} />
<Route
path="/signup"
element={(
<SignupPage
currentuser={currentUser}
setcurrentuser={setCurrentUser}
setusername={setUsername}
/>
)}
/>
<Route path="/login" element={<LoginPage />} />
...
<Route element={<PrivateRoute currentuser={currentUser} />}>
... protected routes ...
<Route
path="/homepage"
element={(
<Homepage
user={currentUser}
username={username}
setusername={setUsername}
/>
)}
/>
...
</Route>
</Routes>
</div>
</Router>
);
}

Why my components don't display on my React page?

So I'm learning React and building an app with multiple pages, I made a Routes file which looks like this:
import 'swiper/swiper.min.css';
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import Catalog from "../pages/Catalog";
import Detail from "../pages/Detail";
const Router = () => {
return (
<Routes>
<Route
path='/:category/search/:keyword'
component={Catalog}
/>
<Route
path='/:category/:id'
component={Detail}
/>
<Route
path='/:category'
component={Catalog}
/>
<Route
path='/'
exact
component={Home}
/>
</Routes>
);
}
And App.js looks like this:
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Header from './components/header/Header';
import Footer from './components/footer/Footer';
import Router from './config/Router';
function App() {
return (
<BrowserRouter>
<Routes>
<Route render={props =>{
<>
<Header {...props}/>
<Router/>
<Footer/>
</>
}}/>
</Routes>
</BrowserRouter>
);
}
export default App;
As you see, I have a browser router and Route which passes props to a component(as I understood) but for some reason the components don't display on the page(original components just have with their name inside of them, but they don't display in App.js).
And my console also says:
No routes matched location "/"
In routes.jsx file. I'm guessing it should lead to main page, but for some reason the route doesn't match and components in App.js don't display.
In Version 6.0.0 there is not any component prop in Route. It has been changed to element. So you need to change your Router to :
const Router = () => {
return (
<Routes>
<Route
path='/:category/search/:keyword'
element={Catalog}
/>
<Route
path='/:category/:id'
element={Detail}
/>
<Route
path='/:category'
element={Catalog}
/>
<Route
path='/'
exact
element={Home}
/>
</Routes>
);
}
As you've said you're using react-router-dom 6.0.2, and it seems that the tutorial you are following is for the older version (5?). There were some breaking changes in version 6.
You need to change your Router component to use element instead of component:
const Router = () => {
return (
<Routes>
<Route path="/:category/search/:keyword" element={<Catalog />} />
<Route path="/:category/:id" element={<Detail />} />
<Route path="/:category" element={<Catalog />} />
<Route path="/" exact element={<Home />} />
</Routes>
);
};
and also your App component seems to be getting in the way with the nested route.
I think it can be simplified to:
function App() {
return (
<BrowserRouter>
<>
<Header />
<Router />
<Footer />
</>
</BrowserRouter>
);
}
You can see a working demo on stackblitz

React router rendering two child components instead of just one

I'm trying to add routes to my application but for some reason there are two components being rendered to the page instead of just one.
My code looks like this (the relevant part):
import React from "react";
import Board from "./Components/Board";
import Navbar from "./Components/Navbar";
import TaskDetail from "./Components/TaskDetail";
import { LanesProvider } from "./Context/lanes.context";
import { TasksProvider } from "./Context/tasks.context";
import { BrowserRouter, Route, Switch } from "react-router-dom";
function App(props) {
const getTask = props => {
return <TaskDetail />;
};
return (
<>
<LanesProvider>
<TasksProvider>
<Navbar />
<Board />
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => <Board />} />
<Route exact path="/board" render={() => <Board />} />
<Route exact path="/board/:taskName" render={() => getTask()} />
</Switch>
</BrowserRouter>
</TasksProvider>
</LanesProvider>
</>
);
}
Now basically when I'm navigating to "localhost/board/test" I would expect to just see the <TaskDetail/> component but instead I get the <Board /> AND <TaskDetail/>.
I didn't expect this to happen because of the exact boolean.
FYI: getTask() is only returning a component right now because I wanted to get the routes to work first before implementing further logic.
So far I could not find a solution to this.
Thank you in advance.
There is a <Board /> component outside your <BrowserRouter>
import React from "react";
import Board from "./Components/Board";
import Navbar from "./Components/Navbar";
import TaskDetail from "./Components/TaskDetail";
import { LanesProvider } from "./Context/lanes.context";
import { TasksProvider } from "./Context/tasks.context";
import { BrowserRouter, Route, Switch } from "react-router-dom";
function App(props) {
const getTask = props => {
return <TaskDetail />;
};
return (
<>
<LanesProvider>
<TasksProvider>
<Navbar />
<Board /> --> Remove this component from here
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => <Board />} />
<Route exact path="/board" render={() => <Board />} />
<Route exact path="/board/:taskName" render={() => getTask()} />
</Switch>
</BrowserRouter>
</TasksProvider>
</LanesProvider>
</>
);
}

Categories

Resources