route router v4 does not reflect component change with Link? - javascript

What's wrong with my route structure? Used Link to navigate couldn't see the changes.
class App extends React.Component {
render() {
return(
<BrowserRouter>
<div>
<AuthRoute></AuthRoute>
<Switch>
<Route path='' component={Home} />
<Route path='/profile' component={Profile} />
</Switch>
</div>
</BrowserRouter>
)
}
}
https://codesandbox.io/s/r433m6kvvp

Changes:
1- Instead of path='' (blank path) use path='/'.
2- Use exact word with path='/' otherwise define that in that last, because if you don't use exact then / will match with /profile or any other route also.
Check the doc for more details about exact and Switch and how they work.
Like this:
<Route exact path='/' component={Home} />
<Route path='/profile' component={Profile} />
or
<Route path='/profile' component={Profile} />
<Route path='/' component={Home} />
Working Code.

Related

How to load multiple routes in index file using react

I have a following index file -
<BrowserRouter>
<Routes>
<Route path="/" element={Home}
<Route element={Navigation}
</Routes>
</BrowserRouter>
I have multiple routes which I have to load So For that I have written a component:
const Navigation = () => {
<>
<Route path="/not-available-primary" element={NotAvaliable}/>
<Route path="/not-available-Secondary" element={Avaliable}/>
<Route path="/available-primary" element={Primary}/>
<Route path="/available-Secondary" element={Secondary}/>
<Route path="/direct-debit-primary" element={DirectDBB}/>
<Route path="/direct-debit-secondary" element={DirectDBBSecondary}/>
</>
}
But here, it does not render the component and gives no routes matched for location.
How do I fix this ?
You have to give a Component to the element prop, like this:
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/*" element={<Navigation />} />
</Routes>
</BrowserRouter>
and
const Navigation = () => {
return (<>
<Route path="/not-available-primary" element={<NotAvaliable />}/>
<Route path="/not-available-Secondary" element={<Avaliable />}/>
<Route path="/available-primary" element={<Primary />}/>
<Route path="/available-Secondary" element={<Secondary />}/>
<Route path="/direct-debit-primary" element={<DirectDBB />}/>
<Route path="/direct-debit-secondary" element={<DirectDBBSecondary />}/>
</>)
}
or
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/*">
<Route path="not-available-primary" element={<NotAvaliable />}/>
<Route path="not-available-Secondary" element={<Avaliable />}/>
<Route path="available-primary" element={<Primary />}/>
<Route path="available-Secondary" element={<Secondary />}/>
<Route path="direct-debit-primary" element={<DirectDBB />}/>
<Route path="direct-debit-secondary" element={<DirectDBBSecondary
/>}/>
</Route>
</Routes>
</BrowserRouter>
Note that in the seconds solution (nested routes) I erased the "/".
Documentation here
in your index file
<Route path="/" compoment={Home}
if "Navigation" is your class
const Navigation = () => {
return (
<>
<Routes>
<Route path="/not-available-primary" component={NotAvaliable}/>
<Route path="/not-available-Secondary" component={Avaliable}/>
<Route path="/available-primary" component={Primary}/>
<Route path="/available-Secondary" component={Secondary}/>
<Route path="/direct-debit-primary" component={DirectDBB}/>
<Route path="/direct-debit-secondary" component={DirectDBBSecondary}/>
</Routes>
</>
)
}
Issue
It's unclear which version of react-router-dom you are trying to use. version 4/5 or 6, but you've syntax issues for either. The route rendering the Navigation component needs a path with a trailing "*" character to be matched at the root/base level so the descendent routes can then also be matched and rendered.
Using react-router-dom#5
Use the Switch component instead of the Routes component. The Route components use the component (or render or children function props). The home path "/" must exactly match in order for any other route to be matched when the path isn't exactly "/", e.g. "/not-available-primary".
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="*" component={Navigation} />
</Switch>
</BrowserRouter>
...
const Navigation = () => {
<Switch>
<Route path="/not-available-primary" component={NotAvaliable} />
<Route path="/not-available-Secondary" component={Avaliable} />
<Route path="/available-primary" component={Primary} />
<Route path="/available-Secondary" component={Secondary} />
<Route path="/direct-debit-primary" component={DirectDBB} />
<Route path="/direct-debit-secondary" component={DirectDBBSecondary} />
</Switch>
};
Using react-router-dom#6
All Route components can only be rendered by a Routes component or another Route component in the case of route nesting. The Route component API changed significantly and there is now only a single element prop taking a ReactNode, a.k.a. JSX, as a value. In RRDv6 all routes are now always exactly matched and use a route ranking system; there is no longer an exact prop for Route components.
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<Navigation />} />
</Routes>
</BrowserRouter>
...
const Navigation = () => {
<Routes>
<Route path="/not-available-primary" element={<NotAvaliable />} />
<Route path="/not-available-Secondary" element={<Avaliable />} />
<Route path="/available-primary" element={<Primary />} />
<Route path="/available-Secondary" element={<Secondary />} />
<Route path="/direct-debit-primary" element={<DirectDBB />} />
<Route path="/direct-debit-secondary" element={<DirectDBBSecondary />} />
</Routes>
};
At the first use <Switch> in Navigation component :
const Navigation = () => {
<Switch>
<Route path="/not-available-primary" component={NotAvaliable}/>
<Route path="/not-available-Secondary" component={Avaliable}/>
<Route path="/available-primary" component={Primary}/>
<Route path="/available-Secondary" component={Secondary}/>
<Route path="/direct-debit-primary" component={DirectDBB}/>
<Route path="/direct-debit-secondary" component={DirectDBBSecondary}/>
</Switch>
}
so, add the component to Route:
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/login" exact component={LoginForm} />
<Route component={Navigation} />
</Switch>
</BrowserRouter>

React router is loading same component for routes defined below that particuler route

I have created routes in app.js and /, /create-receipt and /login routes are working fine but if I go to /signup route or any other route below /login it loads the Login component, if I remove login and signup component then the routes are working perfectly.
App.js:-
<Router>
<Header/>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/create-receipt" component={CreateReceipt} />
<Route Path="/login" component={Login} />
<Route Path="/signup" component={Signup} />
<Route path="/fast-food-receipt" exact component={FastFoodReceipt} />
<Route path="/fast-food-receipt/receipt-one" component={FastFoodReceiptOne} />
<Route path="/fast-food-receipt/receipt-two" component={FastFoodReceiptTwo} />
<Route path="/fast-food-receipt/receipt-three" component={FastFoodReceiptThree} />
<Route path="/fast-food-receipt/receipt-four" component={ReceiptFour} />
<Route path="/fast-food-receipt/receipt-five" component={FastFoodReceiptFive} />
<Route path="" component={NotFound} />
</Switch>
<Footer/>
</Router>
Login.js:-
const Login = () =>{
return(
login page
)
}
export default Login;
Signup.js:-
const Signup = () =>{
return(
signup page
)
}
export default Signup;
NOTE:- issue is coming when i use route component like this
<Route Path="/signup" component={Signup} />
<Route Path="/login" component={Login} />
working fine when i am using route component in this way:-
<Route exact path="/"><Home /></Route>
<Route path="/login"><Login /></Route>
<Route path="/signup"><Signup /></Route>
can some one tell why it is happening

How to put a div inside a Switch with React Router?

I have an APP using React and Redux, and I wanted to load a NotFound component when the user enters an invalid route. I found online a way to solve that problem, that is by putting all the routes inside a switch, including the NotFound component.
The problem is that, in my app, I can't put all my routes inside a Switch because There is a single component that needs to be stretched to the entire page, while all the other components need to be inside a "container". The way I have it below (see the code), the NotFound component works for all cases, except when I'm on the "landing" component route (where the NotFound component always displays).
I tried to put the landing component inside the Switch with the "container" div but the app crashes.
Is there any way to solve this? (keeping the landing component out of the container, and the other components inside)
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:handle" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
<PrivateRoute
exact
path="/add-education"
component={AddEducation}
/>
<PrivateRoute
exact
path="/edit-education/:id"
component={EditEducation}
/>
<PrivateRoute exact path="/feed" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<Route component={NotFound}/>
</Switch>
</div>
<Footer />
</div>
</Router>
</Provider>
);
}
}
You can make a separate router for all other components except landing page.
// App.js
import NonLandingPages from './NonLandingPages';
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Navbar />
<Switch>
<Route exact path="/" component={Landing} />
<Route component={NonLandingPages}/>
</Switch>
<Footer />
</div>
</Router>
</Provider>
);
}
}
Separate router for all other pages
// NonLandingPages.js
class NonLandingPages extends Component {
render() {
return (
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:handle" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
<PrivateRoute
exact
path="/add-education"
component={AddEducation}
/>
<PrivateRoute
exact
path="/edit-education/:id"
component={EditEducation}
/>
<PrivateRoute exact path="/feed" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<Route component={NotFound}/>
</Switch>
</div>
);
}
}

React Router nested routes

I have routes:
<Switch>
<Route path="/about" component={About} />
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Switch>
I would like the /about route to show about component and its children (AboutUs and AboutCompany) but the /about route is only rendering About component. How can I fix that? I have react-router 4
There are 2 ways you can achieve it.
Creating nested routes from routes.js/jsx
Creating nested routes from the parent component (about.js/jsx)
If it is from routes.js/jsx
<Switch>
<Route path="/about" component={About}>
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Route>
</Switch>
If it is from routes.js/jsx
//Routes.jsx/js
<Switch>
<Route path="/about" component={About} />
</Switch>
and
//About.jsx/js
<Switch>
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Switch>
<Switch>
<Route exact path="/about" component={About} />
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Switch>
You need to add the exact keyword to About parent path.

React Routing, refresh does not render specific view, but redirects to parent view

This is our parent view:
http://localhost:8080/#/dashboard/
When I click on a link to Menu Navigation:
http://localhost:8080/#/dashboard/menu-navigation
This will load up the correct menu-navigation view, however if I refresh the app goes back to /dashboard instead of staying on menu-navigation.
From the main Routes.js
const Routes = () => (
<Provider store={store}>
<ConnectedRouter history={history}>
<Switch>
<Route path="/login" exact component={Login} />
<Route path="/redirect" component={FirebaseRedirector} />
<Route path="/restricted-access" component={RestrictedAccess} />
<Route path="/change-password/:hash?" component={ChangePassword} />
<Route path="/reset-password" exact component={ResetPassword} />
<Route path="/" component={Main} />
<Route path="*" component={NotFound} />
</Switch>
</ConnectedRouter>
</Provider>
);
export default Routes;
Note once you are logged in the Main component above is loaded:
render() {
return (
<Main
user={this.props.user}
signOut={this.signOut}
>
<Switch>
<Route
path="/dashboard/categories/unmatched-api/:id?"
component={CategoriesUnmatchedApi}
notExact
/>
<Route path="/dashboard/menu-navigation" exact component={MenuNavigation} />
<Route path="/dashboard/home-screen" exact component={HomeScreen} />
<Route path="/dashboard/categories/product-config" component={CategoryProductConfig} />
<Route path="/dashboard/categories/:category?" component={Categories} />
<Route path="/dashboard/playground" exact component={Playground} />
<Route path="/dashboard" exact component={Drafts} />
<Route path="/" exact component={Drafts} />
<Route path="*" component={NotFound} />
</Switch>
</Main>
);
}
Here is the state once you navigate to the MenuNavigation route
Then the state after refresh
Seems like react router is not respecting <Route path="/dashboard/menu-navigation" ?
I did notice after refresh that the Main.js route section gets hit 3 times, the first time the this.props.location is correct, however the next 2 times it's just /dashboard
Figured it out! We had a redirect to the /dashboard everytime.
Inside our login actions we had:
onAuthStateChange -> checkAuth which contained this:
dispatch(push(authDasboardView));
After removing the dispatch to authDashboardView, this fixed the problem!

Categories