I am new on reactjs and stuck in a scenario like when I login the application using credentials and lands on the dashboard page, after when I navigate to some other page like List page from dashboard and try to refresh the page on list page it take me back to dashboard page instead to stay on the current page i.e List page.
Below is the Route Page of my code.
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/forgotPassword" component={ForgotPassword} />
<Route exact path="/changePassword" component={ChangePassword} />
<PrivateRoutes exact path="/" component={Dashboard} />
<PrivateRoutes exact path="/list" component={List} />
<PrivateRoutes exact path="/listDetails/:id" component={ListDetails} />
</Switch>
</BrowserRouter>
And Private route code is
class PrivateRoute extends Component {
render() {
let componentData = '';
componentData = <div><SideNavigation /> <Route render={() => <this.props.component {...this.props} />} /> </div>;
return componentData;
}
}
Related
I was trying to implement deep links(not sure if this is the correct term) in my react project
what I want to do is this :
the admin gets a mail: "this user can't login: http://localhost:3000/admin/customer-profile/b1d4a11f-4f6c-4dc1-98a9-ac0c30486c16"
the admin is not logged in
the admin clicks the link and is forwarded to the login page
the admin enters his login details
(the new part)
he is forwarded to /admin/customer-profile/b1d4a11f-4f6c-4dc1-98a9-ac0c30486c16
so in the fifth point the admin is redirected to the page link was for instead of going to the homepage.
Below are some snippets to give more info regarding this:
<div className="App">
{ready && <Router basename="/admin">
<Switch>
<Route path="/login">
<Login />
</Route>
<Route path="/privacypolicy">
<PrivacyPolicy />
</Route>
<Route path="/loginhelp">
<Help />
</Route>
<Route path="/termsconditions">
<TermsConditions />
</Route>
<PrivateRoute path="/logout">
<Logout />
</PrivateRoute>
<Route path="/">
<SideBar />
<Switch>
<PrivateRoute path="/tier-list">
<TierList />
</PrivateRoute>
<PrivateRoute path="/privacy-policy">
<PrivacyPolicy />
</PrivateRoute>
<PrivateRoute path="/help">
<Help />
</PrivateRoute>
</Switch>
</Route>
</Switch>
</Router>}
</div>
Below is how PrivateRoute looks like :
function PrivateRoute({ children, ...rest }: any) {
return (
<Route
{...rest}
render={({ location }) =>
userInfo != null ? (
children
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>
)
}
/>
)
}
Any ideas How I shall modify this part to achieve the functionality?
Okay so I solved the problem. What I did was that I passed a pathName prop to the Login component and then if the user was logged in I redirect him to that page but if not then rendered the login page.
These are my public routes
export const PublicRoutes = () => {
return (
<Switch>
<Route path="/" exact component={Login} />
<Route path={constant.component.logout.url} exact={true} component={Logout} />
<Route path={constant.component.register.url} exact= {true} component={SignUp} />
<Route path={constant.component.forgotPassword.url} exact={true} component={ForgotPassword} />
</Switch>
)
}
This is my index.js
ReactDOM.render(
<React.StrictMode>
<AlertProvider template={AlertTemplate} {...options}>
<Router>
<App />
</Router>
</AlertProvider>
</React.StrictMode>,
document.getElementById('root')
);
This is my app.js where I am trying to render routes based on accessToken in the local storage
return (
<>
{token ? <DashboardLayout /> : <PublicRoutes />}
</>
)
And finally this my dashboard layout where I want the authenticated routes to be shown to the right of the sidebar
<>
<SideBar>
<div className="w-100">
<Switch>
<Route path="/dashboard" component={Dashboard} />
<Route path="/my-account" component={Account} />
</Switch>
</div>
<Footer>
</>
Now, when I login, it redirects me to "/dashboard" the url changes but the page shows an empty screen and it works if I refresh the page manually. What am I doing wrong? Thanks
Are you sure your token is not empty right after you login ? Maybe your token is empty at this moment, PublicRoutes is rendered and that's why the /dashboard route display an empty screen. Maybe your token only gets value after refresh.
I am learning about React (Coming from ASP.NET). When I go to '/employee' it will display employee list table. But when I go to '/employee/create' it will display both the table and the create form. How to display only create employee form when I to '/employee/create' ?
export default class App extends Component {
static displayName = App.name;
render() {
return (
<Layout>
<Route exact path='/' component={Home} />
<Route path='/counter' component={Counter} />
<AuthorizeRoute path='/fetch-data' component={FetchData} />
<Route exact path='/employee' component={EmployeeIndex} />
<Route path='/employee/create' component={EmployeeCreate} />
<Route path='/employee/details/:id' component={EmployeeDetails} />
</Layout>
);
}
}
To do that, you will need to add a <Switch> around your Routes:
import { Route, Switch } from "react-router";
<Switch>
<Route exact path='/' component={Home} />
<Route path='/counter' component={Counter} />
<AuthorizeRoute path='/fetch-data' component={FetchData} />
<Route exact path='/employee' component={EmployeeIndex} />
<Route path='/employee/create' component={EmployeeCreate} />
<Route path='/employee/details/:id' component={EmployeeDetails} />
</Switch>
It works just like a normal `switch-case, will only render the first matching path within your Routes.
Without <Switch> it will render ALL matching routes.
Here what I use in my apps.
Make separate components for all pages and import in App.js under src. Make use of state and props to store the data and create ID. Install npm i react-router-dom to access react route.
import { Switch, Route, Redirect } from "react-router-dom";
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/employee" component={Employee} />
<Route exact path="/createEmployee" component={Create} />
<Route exact path="/employeeDetails" component={Details} />
<Redirect to = "/" />
</Switch>
for homepage - Home.js
for employee list table - Employee.js
create employee - Create.js
go to employee's detail - Details.js
Redirect to - will redirect to homepage if exact URL is not entered.
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!
I have a repo to reproduce this and see the error: https://github.com/rublev/parcel-static1/tree/master
The basic structure of my routes is as follows:
// app/app.js
const render = Component => {
ReactDOM.render(
<AppContainer>
<Provider store={ store }>
<ConnectedRouter history={ history }>
<Route component={ Component } />
</ConnectedRouter>
</Provider>
</AppContainer>,
document.getElementById('react-root')
)
}
// app/containers/App/index.js
<div className='app'>
<Switch location={ location }>
<Route exact path='/' render={() => (
loggedIn ? (
<Redirect to='/organizations' push />
) : (
<Redirect to='/onboarding' push />
)
)}/>
<Route path='/organizations' component={ Organizations } />
<Route path='/onboarding' component={ Onboarding } />
<Route path='/settings' component={ Settings } />
</Switch>
</div>
// app/flows/onboarding/Onboarding/index.js
<div>
<Route exact path={`${match.url}`} component={ Start }/>
<Route path={`${match.url}/signup`} component={ SignUp }/>
<Route path={`${match.url}/name`} component={ Name }/>
<Route path={`${match.url}/structure`} component={ Structure }/>
<Route path={`${match.url}/pricing`} component={ Pricing }/>
<Route path={`${match.url}/continue`} component={ Continue }/>
</div>
// app/flows/onboarding/Start/index.js
<div className='start'>
Start Page
</div>
I'm not sure where the error could be coming from or how to do this different.
I have three main routes:
/onboarding
/organizations
/settings
I'd like to redirect to either /onboarding or /settings depending on login state. Once at either of these main routes, there will be sub routes.
What is the proper way to set these routes up with a redirect without causing a redirect error?
error on launching localhost:8080/:
In your render function, change
<Route component={ Component } />
to
<Component />
Also, you shouldn't need to pass location as a prop into the Switch in App.