I'm trying to implement router in react-create-app but it always render "/" and showing Home or SignIn page. How can I solve this?
function AppRouter({ isLoggedIn, user }) {
return(
<Router>
<Routes>
<Route path="/profile" element={<Profile />} />
<Route path="/signUp" element={<SignUp />} />
{isLoggedIn
? <Route exact path={"/"} element={<Home user={user}/>} />
: <Route exact path={"/"} element={<SignIn />} />
}
</Routes>
</Router>
)
}
It seems you have a slight misunderstanding of how the HashRouter works with the UI.
import { HashRouter as Router, Route, Routes } from "react-router-dom";
import Profile from "./Profile";
import SignUp from "./SignUp";
import Home from "./Home";
export default function App() {
return (
<Router>
<Routes>
<Route path="/profile" element={<Profile />} />
<Route path="/signUp" element={<SignUp />} />
<Route path="/" element={<Home />} />
</Routes>
</Router>
);
}
The HashRouter handles routing with a URL hash value, i.e. everything after the "#" in the URL. If you are trying to render your app and access "<domain>/" instead of "<domain>/#/" the routing won't work.
For example in your running codesandbox demo, the base URL is "https://5p7hff.csb.app/". At this base URL the hash router isn't really working, and you should really be accessing "https://5p7hff.csb.app/#/" instead so the hash router is loaded and the app's internal routing can work.
From "https://5p7hff.csb.app/#/" you should be to then navigate to any of your routes, i.e. "https://5p7hff.csb.app/#/profile" and https://5p7hff.csb.app/#/signUp".
If you switch to a different router, like the BrowserRouter then the "/#/" is no longer used, the router and routes render from "/" where the app is running from. The routes would be "https://5p7hff.csb.app/", "https://5p7hff.csb.app/profile", and "https://5p7hff.csb.app/signUp".
Related
I have created a react application with a home page and survey containing 15 questions on 15 pages.
I used a BrowserRouter to wrap the home page in the '/' route. I listed the 15 pages under the MemoryRouter to make it display under the '/apply' route. The issue here is the initial entry is visible in the '/' route. MemoryRouter should not be visible in the '/' route. It should be there on the '/apply' path alone.
import React from "react";
import BusinessType from "./BusinessType";
import {
BrowserRouter as Router,
MemoryRouter,
Routes,
Route
} from "react-router-dom";
import Howmuch from "./Howmuch";
import Seeking from "./Seeking";
import Date from "./Date";
import AnnualRevenue from "./Annualrevenue";
import Creditscore from "./Creditscore";
import BusinessName from "./BusinessName";
import Industry from "./Industry";
import Deposit from "./Deposit";
import Zipcode from "./Zipcode";
import Name from "./Name";
import Phone from "./Phone";
import Email from "./Email";
import Home from "./Pages/Home";
import Require from "./Require";
import Apply from "./Apply";
function App() {
return(
<div>
<Router>
<div>
<Routes>
<Route exact path='/' element={<Home />} />
</Routes>
</div>
</Router>
<MemoryRouter initialEntries={['/apply']} initialIndex={0}>
<Routes>
<Route path='/apply' element={<BusinessType />} />
<Route path='/Qn2' element={<Howmuch />} />
<Route path='/Qn3' element={<Seeking />} />
<Route path='/Qn4' element={<Date />} />
<Route path='/Qn5' element={<AnnualRevenue />} />
<Route path='/Qn6' element={<Creditscore />} />
<Route path='/Qn7' element={<BusinessName />} />
<Route path='/Qn8' element={<Industry />} />
<Route path='/Qn9' element={<Deposit />} />
<Route path='/Qn10' element={<Zipcode />} />
<Route path='/Qn11' element={<Name />} />
<Route path='/Qn12' element={<Phone />} />
<Route path='/Qn13' element={<Email />} />
<Route path='/final' element={<Require />} />
<Route path='/congrats' element={<Apply />} />
</Routes>
</MemoryRouter>
</div>
);
}
export default App;
If I'm understanding your post and comments correctly it seems you are saying that the BusinessType component is being rendered even though the current URL path is "/". The issue here is that the MemoryRouter path matching isn't coupled to the browser's address bar and you've initialized to "/apply" and so that is the "path" that is matched and rendered regardless what the URL is in the browser's address bar.
I used two separate routers because all pages of the survey should be
under the '/apply' route.
In this case I'd suggest rendering all these routes in the main BrowserRouter under the appropriate route paths.
Example:
import React from "react";
import BusinessType from "./BusinessType";
import {
BrowserRouter as Router,
Routes,
Route
} from "react-router-dom";
...
function App() {
return(
<div>
<Router>
<div>
<Routes>
<Route path='/' element={<Home />} />
<Route path="/apply">
<Route index element={<BusinessType />} /> // "/apply"
<Route path='/Qn2' element={<Howmuch />} /> // "/apply/qn2"
<Route path='/Qn3' element={<Seeking />} /> // "/apply/qn3"
<Route path='/Qn4' element={<Date />} /> // "/apply/qn4"
...
<Route path='/Qn12' element={<Phone />} /> // "/apply/qn12
<Route path='/Qn13' element={<Email />} /> // "/apply/qn13
<Route path='/final' element={<Require />} /> // "/apply/final"
<Route path='/congrats' element={<Apply />} /> // "/apply/congrats"
</Route>
</Routes>
</div>
</Router>
</div>
);
}
export default App;
I'm using react-router-dom V6
<Router>
<Routes>
<Route path="/">
<Route path="example" element={<h1>Example</h1>}>
<Route path=":id" element={<p>cool</p>} />
</Route>
</Route>
</Routes>
</Router>
"http://localhost:3000/example " renders Example so far good, but
"https://localhost:3000/example/34" renders nothing.
What is the problem?
Please provide a why and how to solve this issue.
When nesting routes, the parent routes need to render an Outlet component for the nested routes to render their element content into. Route components render an Outlet by default when no element prop is provided, so this is why the "/example" route works.
Example:
import {
BrowserRouter as Router,
Routes,
Route,
Outlet,
} from 'react-router-dom';
...
<Router>
<Routes>
<Route path="/">
<Route
path="example"
element={(
<>
<h1>Example</h1>
<Outlet />
</>
)}
>
<Route path=":id" element={<p>cool</p>} />
</Route>
</Route>
</Routes>
</Router>
If you don't want to render the "Example" component at the same time as its children, then render it alone on its own index route.
Example:
<Router>
<Routes>
<Route path="/">
<Route path="example">
<Route index element={<h1>Example</h1>} />
<Route path=":id" element={<p>cool</p>} />
</Route>
</Route>
</Routes>
</Router>
For more details, see:
Routes and Route
Layout Routes
Outlet
I am making a project and getting some problem in managing routes. My Frontend is divided in two parts. One For the Client side and onother is the admin-panel for handling the Client side. For example if I add some Blog from admin-panel then it shows on Client-side. Admin-Panel is for my team to handle the website. Suppose Users will visit on my website at "www.mywebsite.com' and I want that if I enter "www.mywebsite.com/admin" then Admin-panel and Admin-components should open instead of Nav-Components.
How Do I achieve this conditional routing?
Here is the App.js
import React, { Component, useEffect, useState } from "react";
import { Route, Switch } from "react-router-dom";
import Landing from "./components/Landing";
import Home from "./components/Home";
import About from "./components/About";
import Teams from "./components/Team";
import Events from "./components/Events";
import NotFound from "./components/NotFound";
import Blog from "./components/Blog";
import ContactUs from "./components/Contact";
import ComingSoon from "./components/ComingSoon";
import Navbar from "./components/Navbar";
import EventInfo from "./components/EventInfo";
import AdminNavbar from "./admin-panel/AdmiNavbar";
import Login from "./admin-panel/Login";
import Eventadd from "./admin-panel/Eventadd";
import Blogadd from "./admin-panel/Blogadd";
import Dashboard from "./admin-panel/Dashboard";
const NavComponents = () => {
return (
<>
<Switch>
<Route path="/home" exact component={Home} />
<Route path="/about" exact component={About} />
<Route path="/events" exact component={Events} />
<Route path="/team" exact component={Teams} />
<Route path="/blog" exact component={Blog} />
<Route path="/contact" exact component={ContactUs} />
<Route path="/comingsoon" exact component={ComingSoon} />
<Route path="/eventinfo/:eventName" exact component={EventInfo} />
<Route component={NotFound} />
</Switch>
</>
);
};
const AdminPanel = () =>{
return(
<>
<Switch>
<Route path="/admin/Eventadd" exact component={Eventadd}/>
<Route path="/admin/Blogadd" exact component={Blogadd}/>
<Route path="/admin/DashBoard" exact component={Dashboard}/>
<Route component={NotFound} />
</Switch>
</>
);
};
class App extends Component {
render() {
return (
<>
{window.location.pathname=="/"?"": <Navbar />}
<Switch>
<Route path="/" exact component={Landing} />
<NavComponents />
</Switch>
</>
);
}
}
export default App;
I assume if users enter your website through "www.mywebsite.com/admin" link, you want to re-route them to "/admin/DashBoard" route? The admin dashboard doesn't show because, it only returns the route with EXACT match. It's possible to
A) Add an additional path to handle the routing
<Route path=["/admin/DashBoard", "/admin"] exact component={Dashboard}/>
B) Add a Redirect for admin if you prefer to keep the route as /admin/dashboard
<Redirect exact from="/admin" to={`/admin/dashboard`} />
Edit: (Most importantly)
Also, noticed that you did not include the admin into the main router. You don't need to separate the admin from nav. Suggest to read on the document
https://reactrouter.com/web/api/Switch
Switch renders the first child <Route> or <Redirect> that matches the location.
Overall, it should be combined like this
<Switch>
...user paths
...admin paths
</Switch>
I am working with react router on a small project. I initially had my AppRouter working with BrowserRouter and everything works fine. But I had to switch to Router so I could add my own history object. With Router my page navigations do not work, instead it jumps straight to my 404 page. Any suggestions on what I am doing wrong will be appreciated.
import React from "react";
import AddExpensePage from "../components/AddExpensePage";
import EditExpensePage from "../components/EditExpensePage";
import ExpenseDashboardPage from "../components/ExpenseDashboard";
import Header from "../components/Header";
import HelpPage from "../components/HelpPage";
import NotFoundPage from "../components/NotFoundPage";
import { createBrowserHistory } from "history";
import LoginPage from "../components/LoginPage";
import { Switch, BrowserRouter, Route, Router } from "react-router-dom";
export const history = createBrowserHistory();
const AppRouter = () => (
<Router history={history}>
<div>
<Header />
<Switch>
<Route path="/" component={LoginPage} exact={true} />
<Route path="/dashboard" component={ExpenseDashboardPage} />
<Route path="/create" component={AddExpensePage} />
<Route path="/edit/:id" component={EditExpensePage} />
<Route path="/help" component={HelpPage} />
<Route component={NotFoundPage} />
</Switch>
</div>
</Router>
);
export default AppRouter;
I would suggest that you keep using BrowserRouter. React Hooks now make using history possible despite the type of Router you're using.
From ReactRouter documentation, useHistory is there to your rescue:
The useHistory hook gives you access to the history instance that you may use to navigate.
To access the history object anywhere in your app inside the Routed Components, you can do the following inside of that component:
let history = useHistory();
Then you have access to history.push() and other methods you wish to call to fiddle with history.
Conclusion:
Don't switch to <Router>, keep using <BrowserRouter> and use hooks to access history using useHistory.
You have to wrapp your routes with BrowserRouter component, for example:
const AppRouter = () => (
<Router history={history}>
<div>
<Header />
<BrowserRouter>
<Switch>
<Route path="/" component={LoginPage} exact={true} />
<Route path="/dashboard" component={ExpenseDashboardPage} />
<Route path="/create" component={AddExpensePage} />
<Route path="/edit/:id" component={EditExpensePage} />
<Route path="/help" component={HelpPage} />
<Route component={NotFoundPage} />
</Switch>
</BrowserRouter>
</div>
</Router>
);
For a invalid route, I want to show the NotFound component, but also not show the Navigation component:
const Layout: React.FunctionComponent = () => {
return (
<Router>
<Navigation />
<Switch>
<Route path="/explore" exact>
<ExploreIndex />
</Route>
<Route path="/explore/:id" exact>
<ExploreShow />
</Route>
<Route path="/" exact>
<Home />
</Route>
<Route component={NotFound} />
</Switch>
</Router>
);
};
If I go to /aaaaaaa, my NotFound component loads but so does my Navigation. How can I not have Navigation render for such routes?
What about just rendering it as another route?
<Route path={['/explore', '/explore/:id', '/']} exact component={Navigation} />
It will not be rendered if the route does not match any of the routes listed in the path array.
You can add NavigationBar in the specific components rather than app.js. So for example if there is a about page, place NavigationBar on top of the component