React Router Link Not Working After Render in IE - javascript

I have run into an issue where React Router's NavLink is not working upon the initial render of a dashboard screen, after a successful login. After trying many different things I am posting here. You probably won't know why either but its worth a shot.
An example layout of the dashboard is as follows:
<div>
<nav>
<NavLink>Link 1</NavLink>
<NavLink>Link 2</NavLink>
<NavLink>Link 3</NavLink>
<NavLink>Link 4</NavLink>
</nav>
<div>
<!-- CONTENT -->
</div>
</div>
Upon initial render Link 2 will be unresponsive, while Link 1, 3, and 4 work fine. Clicking Link 3 for example will render new elements in the content section and then Link 2 will work.
I have tried even changing the NavLinks to anchor tags and adding my own click handler, but no matter what I try the second Link will not work until some mysterious event takes place.
Any ideas?
Edit* Add routes for #arracso
Authenticated Route:
<Switch>
<Route path="/route-1" component={SomeComponent} />
<Route path="/*" component={Dashboard} />
</Switch>
Dashboard:
<Row>
{navigationElement}
<Column>
<Switch>
<Route path="/1" component={A} />
<Route exact path="/2" component={B} />
<Route path="/2/1" component={C} />
<Route path="/2/1" component={D} />
</Switch>
</Column>
</Row>

Related

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

Route from one component to another reactjs

I have my app like that
<Router>
<div className="App">
<Link to="/" style={{ textDecoration: "none" }}>
<header>Project Issues</header>
</Link>
<Switch>
<Route exact path="/">
<Issues />
</Route>
</Switch>
</div>
</Router>
Inside Issues component, I choose to render one of two components based on a window width condition, one of the two components is called TwoPagesLayout, in this component when the user clicks on some text, it should go to another component called IssueDetails.
Here's the part of the TwoPagesLayout component:
{issues.map((issue: any) => (
<div>
<Link to="/Details" style={{ textDecoration: "none" }}>
<p className="issue-title">{issue.title}</p>
</Link>
<hr></hr>
<Switch>
<Route exact path="/Details">
<IssueDetails issue={issue} />
</Route>
</Switch>
</div>
))}
The problem is when I click on the text, it goes to that url "http://localhost:3000/Details" but it appears as a blank white page, it doesn't render what is inside the page.
Hope I have made it clear, I am new to react so I think the question maybe sounds common.
<Route exact path="/">
<Issues />
</Route>
Since you've marked this as exact, once the url changes to /Details, it no longer matches, and so Issues unmounts. Since Issues unmounts, so too does its descendant IssueDetails. You probably want to do:
<Route path="/">
<Issues />
</Route>
The Issues component will only render on the "/" path. When the page is showing "/Details" the Issues component will not render, and that includes the nested Router.
For this reason (they’re confusing), I personally try to avoid nested routers, so I would suggest keeping all the Route components together unless you have a reason otherwise!

How to load first menu item by default with a different Router Link

I have React Router setup in my Reactjs Project. The header Component has 4 different menu items. After login, I am getting only header component rendered but not first menu item component below it.
I have created a Homepage component which loads Header component and below that I gave Routes for different menu item pages. In the Header component for every Item, I linked it to the corresponding Item Page.
//Home Page Code.
<Router>
<Header />
<Route path='/Jobs' component={Jobs} />
<Route path='/Admin' component={Admin} />
<Route path='/Requests' component={Requests} />
</Router>
To use react router you have to wrap your routes in switch.
Switch will render the first item that matches the current route.
Because you have no switch, the routes are ignored.
To render a default site, change the path of the last route to / and it will match everything.
By setting it as last element, it will always be rendered, if no other route above matches the current route.
<Router>
<Header />
<Switch>
<Route path='/Jobs' component={Jobs} />
<Route path='/Admin' component={Admin} />
<Route path='/' component={Requests} />
</Switch>
</Router>
Hope this helps. Happy coding.
Try putting <Switch></Switch> container around your routes:
//Home Page Code.
<Router>
<Header />
<Switch>
<Route exact path='/' component={Home} />
<Route path='/Jobs' component={Jobs} />
<Route path='/Admin' component={Admin} />
<Route path='/Requests' component={Requests} />
</Switch>
</Router>
Edited: to add path for home (path='/')

How to use routes in two different components - ReactJS

I am creating an application using ReactJS. I am using react router v4 from react-router-dom.
I have written routes in index.js file.
<BrowserRouter>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path='/dashboard' component={Viewport} />
</Switch>
</BrowserRouter>
Rest of the application in Viewport.js file.
return (
<div className="">
<Sidebar navigation={this.viewport} />
<HeaderBanner user={this.props.user} />
<div className="center-panel">
//todo
//Can I use router here?
</div>
</div>
)
After user login's, I am rendering Viewport which contains Sidebar and header bar by default. Based on the item click in the sidebar navigation, I need to render components dynamically. As of now, if I write anything in the place of todo, it renders only that component for the complete browser window.
Is there any way to use routers in multiple places of the application? If yes, how can I implement it? If no, what's the best solution?
As far as I have seen, routers will be stacked at one place in the application.
Thanks in advance.
I followed a tutorial on youtube recently which was very useful
So I took some of it and applied it to your setup
<BrowserRouter>
<div>
<Route exact path="/" component={Login} />
<Route exact path='/dashboard' component={Viewport} />
</div>
</BrowserRouter>
import { NavLink, Route } from 'react-router-dom';
class Viewport extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div className="Side-bar">
<NavLink
activeClassName="active"
to={`${this.props.match.url}/sub-page-name-1`}>Sub Page 1</NavLink>
<NavLink
activeClassName="active"
to={`${this.props.match.url}/sub-page-name-2`}>Sub Page 2</NavLink>
<NavLink
activeClassName="active"
to={`${this.props.match.url}/sub-page-name-3`}>Sub Page 3</NavLink>
</div>
<HeaderBanner user={this.props.user} />
<div className="center-panel">
<Route path={`${this.props.match.url}/sub-page-name-1`} component={SubPagePanel1} />
<Route path={`${this.props.match.url}/sub-page-name-2`} component={SubPagePanel2} />
<Route path={`${this.props.match.url}/sub-page-name-3`} component={SubPagePanel3} />
</div>
</div>
)
}
}
I removed Switch as well because I didn't use it for my sub pages... :-S
Update: Have created a repo showing a working example of sub page content
https://github.com/PocketNinjaDesign/so-sub-routes-answer
Yes you can use <Routes> in as many places as you want. <Router> components are the ones you can only use once.

React Router v4 nested route to change the entire content

I have been trying to understand how to apply the concept of nested routes to my scope.
I need these routes:
/projects
Title
List
NavLink to /projects/new
This route will have a list of projects and a button to create a new project.
/projects/new
Form
NavLink to close and go to /projects
When this route is called, will appear a panel above the content, it doesn't change the page projects.
/projects/:projectId/dashboard
Dashboard Title
List of items
When a project is selected, I need to show its dashboard in a whole new page, different than the /projects
My react route config:
<Switch>
<Route exact path='/home' component={Home}/>
<Route path='/home' component={Home}/>
<Route path='/projects' component={Projects} />
<Redirect to="/home" push />
</Switch>
My render inside projects to receive the other route:
<section className='content projects'>
<div>
<h3>List</h3>
<ul>{list}</ul>
</div>
<Route path='/projects/new' render={
() => {
return <div>
<h3>New Project</h3>
<form action="#">
<input type="text" placeholder='Contract name'/>
<input type="text" placeholder='Project name'/>
<button type="submit">Create</button>
</form>
<NavLink to='/projects'>Close</NavLink>
</div>
}
} />
</section>
Now, where should I put this route:
<Route path='/projects/:projectId/dashboard' component={Dashboard} />
I thought if I put inside the switch, would work, but the page gets blank.
Anyone can help me with this? =)
Thanks!
UPDATE 1
I tried to put my dashboard route above /projects with exact.
Now I'm getting a blank content where it should appear the Dashboard component. The route for projects is still working normally.
<Switch>
<Route exact path='/' component={Home}/>
<Route exact path='/projects/:projectId/dashboard' render={ () => {
return <h2>Dashboard</h2>
}} />
<Route path='/projects' component={Projects} />
<Redirect to="/home" push />
</Switch>
UPDATE 2
I have created a separated project and it worked with the answer in this topic. Now I will try to figure out why it didn't work in the project that I'm having blank page.
Try adding the exact prop to the Route and make sure that it appears BEFORE /projects in the Switch:
<Switch>
<Route exact path='/home' component={Home}/>
<Route path='/home' component={Home}/>
<Route exact path='/projects/:projectId/dashboard' component={Dashboard} />
<Route path='/projects' component={Projects} />
<Redirect to="/home" push />
</Switch>
What's happening is your first /projects is matching any route that starts with /projects. Adding the exact prop will make sure that if the route matches /projects/:projectId/dashboard exactly, it will render Dashboard.

Categories

Resources