react router not rendering components at route - javascript

My root component is shown below:
ReactDOM.render(
<Provider store={store}>
<Router>
<Menu />
<Switch>
<Route path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
</Switch>
</Router>
</Provider>,
document.getElementById('root')
)
and then my Menu component is shown below:
function Menu() {
return (
<ul className='menu'>
<li className='menu-item'>
<Link to='/'>Home</Link>
</li>
<li className='menu-item'>
<Link to='/about'>About</Link>
</li>
</ul>
)
}
export default withRouter(Menu)
The problem is that when I click the relevant link, my About component does not render but the url shows up in the url bar. I am not sure what's wrong and I have gone through all of the questions related to this topic and none of their suggestions have helped me. I am using redux but I do not think that is what is causing the problem. Please help!

As mentioned, the exact prop should be added to the route that renders the Home component:
<Router>
...
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
...
</Router>
The reason for that is to restrict rendering of the Home component to an exact match of "/". Without the exact prop, the Home component will also be rendered for other partially matched routes (ie "/about", which would be considered a partial match).
Some other suggestions; you might consider assigning the component rendered for a route via the component prop on the Route component by doing this:
<Route exact path="/" component={Home} />
Additionally, you can avoid wrapping the Menu component with the withRouter.
For a working example, see this link - hope these pointers help! :)

add exactto your rout, like this
<Route exact path='/'>
<Home />
</Route>
<Route exact path='/about'>
<About />
</Route>

Use the Router logic like this.
<Provider store={store}>
<Router>
<Menu />
<Switch>
<Route path='/' exact component = {Home}/>
<Route path='/about' exact component = {About}/>
</Switch>
</Router>
</Provider>,

Related

Layout is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>. How should I overcome this error?

<Routes>
<Route exact path='/'>
<Layout>
<Home></Home>
</Layout>
</Route>
</Routes>
Layout consists of header and footer, I want to wrap my home inside Layout.
React 18.1.0
react-router-dom 6.0.2
Other Route components are the only valid children of a Route component. This is the use case of building nested routes. For routed content/components, these must use the element prop.
Render the Layout component as the element of the Route component.
Example:
<Routes>
<Route
path='/'
element={(
<Layout>
<Home />
</Layout>
)}
/>
</Routes>
It also common to have layout components render an Outlet for nested routes.
Example:
const Layout = () => (
<>
<Header />
<Outlet />
<Footer />
</>
);
...
<Routes>
<Route element={<Layout />}>
<Route path='/' element={<Home />} />
</Route>
</Routes>
You could just extract the <Home/> component from there and provide the layout as a prop to the Route like this
<Route component={Layout} />
And provide your home component inside the Layout component it self

How to configure the Routes in Sidebar navigation after Login page in React?

I am designing a users dashboard in React, wherein User logs in and navigate to his dashboard with other links such as Archived, Profile and Settings. My Login and then Navigating to HomePage is working fine.
I have designed the Dashboard, Archived, Profile and Settings Page Links in Sidebar. Now when I am navigating to the Links. It takes me to a new URL path and my Sidebar disappears. I want my sidebar to still appear on all pages as long as I am logged in.
Below is my App.js where I have designed the upper level route:
return (
<div>
<Router history={history}>
<Switch>
<PrivateRoute exact path="/" component={HomePage} />
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
<Redirect from="*" to="/" />
</Switch>
</Router>
</div>
);
Once User is on HomePage, I need the dashboard and other links to show. and when User clicks on any Sidebar link, Sidebar should still be there while the other page opens. So I added the inner Routes to the HomePage.jsx like this:
return (
<div>
<Router history={history}>
<Sidebar />
<Switch>
<Route path="/" component={Dashboard} />
<Route path="/archived" component={ArchivedPage} />
<Route path="/profile" component={ProfilePage} />
<Route path="/settings" component={SettingsPage} />
{/* <Redirect from="*" to="/" /> */}
</Switch>
</Router>
</div>
);
But it doesn't work. Can anyone please help me understanding if this is correct. or how can I achieve the required result.
Please let me know if you need any other details.
Thank you.
Issue
The issue is that you are exactly matching "/" to render HomePage, but then as soon as the path is any deeper, like "/archived", it no longer exactly matches and HomePage is unmounted.
You should not render a Router within another Router, you need only one router per app to provide the routing context.
Solution
Remove the inner router (and any other nested routers!!). Remove the exact prop on the "/" path and reorder the routes to specify the more specific paths before less specific paths so the Switch can actually do its job and match and render the appropriate route.
App
Reorder the more specific "/login" and "/register" paths to be matched prior to the less specific "/" path. If you had, for example, a "/login/google" path, this is more specific than "/login" and would be ordered earlier.
return (
<div>
<Router history={history}>
<Switch>
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
<PrivateRoute path="/" component={HomePage} />
<Redirect to="/" />
</Switch>
</Router>
</div>
);
HomePage
Move the Dashboard to the last route position so if no other route above it is matched and returned then the dashboard is matched and rendered.
return (
<div>
<Sidebar />
<Switch>
<Route path="/archived" component={ArchivedPage} />
<Route path="/profile" component={ProfilePage} />
<Route path="/settings" component={SettingsPage} />
<Route component={Dashboard} />
</Switch>
</div>
);
in first place your doing something wrong you cant put a Router inside a Router,
you haver a Router in app then inside a component that is inside of app you have another Router thats a problem i dont know if that solves your problem but try it just delete Router in homepage

How to use {Switch, Route} in hierarchical components in React?

I have routes in App.js mainly Logout, Signin and Home.
Inside App.js :
return(
<>
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/signin' component={Signin} />
<Route exact path='/logout' component={Logout} />
</Switch>
</>)
Also, I want Routes inside Home.js :
return(
<>
<Navbar/>
<Switch>
<Route exact path='/'>
<LandingPage />
</Route>
<Route exact path='/settings'>
<Settings username={username} />
</Route>
</Switch>
</>
)
The LandingPage component is default for Home page, and Navbar is common in both LandingPage and Settings.
LandingPage component is showing perfectly but when I click "settings" button from Navbar, the Settings component is not showing. Other Routes are working fine.
Inside Navbar I used NavLink:
<NavLink className="nav-link" to="/">
HOME
</NavLink>
<NavLink className="nav-link" to="/settings">
SETTINGS
</NavLink>
Why the Settings Component is not showing ???
<Route exact path='/' component={Home} />
Because of the exact flag, anything that isn't precisely "/" will not match this. So when the url becomes "/settings", you stop rendering your Home component, which in turn means there's nothing trying to render a route at "/settings"
The likely fix is to remove the exact, and also rearrange your components so this case comes after the sign in/sign out cases:
<Switch>
<Route exact path='/signin' component={Signin} />
<Route exact path='/logout' component={Logout} />
<Route path='/' component={Home} />
</Switch>

react router v4 route changed but did not render the correct component

I have 2 level of route, the first layer it look like this
<BrowserRouter>
<div>
<AuthRoute></AuthRoute>
<Switch>
<Route path='/dashboard' component={Dashboard} />
</Switch>
</div>
</BrowserRouter>
where in AuthRoute I have a redirect upon componentDidMount
this.props.history.replace(/dashboard/redirected)
The problem is within the dashboard/index which is my 2nd level of route config
<BrowserRouter>
<Switch>
<Route exact path='/dashboard' component={()=><h1>dashboard index</h1>} />
<Route exact path='/dashboard/somewhere' component={()=><h1>somewhere</h1>} />
<Route exact path='/dashboard/redirected' component={() => <h1>redirected</h1>} />
</Switch>
</BrowserRouter>
The route changed to /dashboard/redirect but the component didn't render the correct one if you refresh on says /dashboard/somewhere or /dashboard/
You can see the problem clearer in the demo I setup https://codesandbox.io/s/v0v4qok38l
You only need one <BrowserRouter> in the application - removing it from dashboard/index.js will fix your issue.

React Router v4 Nested Routes with Switch

Trying to do the following, but it's not working.
ReactDOM.render(
<Router>
<div className="route-wrapper">
<Switch>
<App>
<Route exact path="/" component={HomePage} />
<Route path="/user" component={UserPage} />
</App>
<Route component={Err404} />
</Switch>
</div>
</Router>,
document.getElementById('main')
)
As the documentation says only Route and Redirect elements are allowed inside a Switch element. How do I get this to work without explicitly wrapping HomePage and UserPage in App or having the error page wrapped by App?
While I have begun developing a "Universal React app", where the first page load is done with server-side rendering, I faced similar problem as the React-Router had just updated to 4.0. You should consider restructuring you application something as given below:
ReactDOM.render(
<Router>
<div className="route-wrapper">
<Switch>
<Route path="/" component={App} />
<Route component={Err404} />
</Switch>
</div>
</Router>,
document.getElementById('main')
)
Where the App component is refactored as following:
class App extends React.Component {
render() {
return <div>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/user" component={UserPage} />
</Switch>
</div>;
}
}

Categories

Resources