Reputation: 331
Hello guys i created a new action to login user like this :
import * as types from './actionTypes';
import sessionApi from '../api/SessionApi';
import auth from '../auth/authenticator';
export function loginSuccess() {
return {type: types.LOG_IN_SUCCESS}
}
export function loginUser(credentials) {
return function(dispatch) {
return sessionApi.login(credentials).then(response => {
sessionStorage.setItem('token', response.token);
dispatch(loginSuccess());
}).catch(error => {
throw(error);
});
};
}
export function logOutUser() {
auth.logOut();
return {type: types.LOG_OUT}
}
and i create a session reducer for my auths like this :
import * as types from '../actions/actionTypes';
import initialState from './initialState';
export default function sessionReducer(state = initialState.session,
action) {
switch(action.type) {
case types.LOG_IN_SUCCESS:
// history.push('/restaurant')
return !!sessionStorage.token
default:
return state;
}
}
after the login success i want to redirect my user to another page bu using history.push but i don't know how to do that ?? i try to first import
import createBrowserHistory from "history/createBrowserHistory"
and then create a new const history like that :
export const history = createBrowserHistory({
forceRefresh: true
})
and then
history.push('/restaurant')
but after the action, that redirect me from /#home to /restaurant/#home .... and not to my right component . I have 2 routes file one for my main views like this :
const routes = [
{ path: '/', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/home', name: 'Landing', component: Landing },
{ path: '/dishes', exact: true, name: 'Detail', component: Dish },
{ path: '/dishes/detail', name: 'DishDetail', component: Detail },
{ path: '/checkout/registration', name: 'Restaurant', component:
Registration },
];
export default routes;
and one for all my restaurant views like this :
const routes = [
{ path: '/restaurant', exact: true, name: 'Restaurant', component:
RestrauntDashboard },
{ path: '/restaurant/dashboard', name: 'Restaurant Dashboard',
component: Dashboard },
{ path: '/restaurant/profile', name: 'Restaurant Dashboard', component:
Profile },
];
export default routes;
and this is my app.js :
class App extends Component {
render() {
return (
<HashRouter>
<Switch>
<Route path="/restaurant" name="Restaurant" component= .
{RestrauntDashboard} />
<Route path="/" name="Home" component={Home} />
</Switch>
</HashRouter>
);
}
}
export default App;
So finally i want to redirect the user in the '/restaurant/ path after he logged in , by using history.push , thank you for your help
Upvotes: 2
Views: 25436
Reputation: 515
Change your Login Component to look like this.
import React from 'react';
import {Redirect} from "react-router-dom";
import {withRouter} from "react-router-dom";
import {compose} from 'redux';
import {connect} from 'react-redux';
const Login = props => {
return (
<div>
/*all login UI */
//..
{
props.isLoggedIn ?
<Redirect to={'/restaurant'}/> : null
}
</div>
)
};
const mapStateToProps = state => ({
isLoggedIn: state.session.isLoggedIn //or whatever
});
export default compose(
withRouter,
connect(mapStateToProps, mapDispatchToProps)
)(Login);
Change your sessionReducer like below
export default function sessionReducer(state = initialState.session, action) {
switch(action.type) {
case types.LOG_IN_SUCCESS:
return { ...state, isLoggedIn: true}
default:
return state;
}
}
When the user is not logged in the isLoggedIn
is undefined so it renders nothing but when login is successful, some value assigned to token, as the result <Redirect to='/restaurant'/>
will be rendered and the site will be redirected to /restaurant
If an error arises about isLoggedIn is undefined add this to initialState.js
const initialState = {
//..
session: {
//.. others
isLoggedIn: false
}
}
Hope this solves your issue. Cheers!
Upvotes: 0
Reputation: 4862
Adding to Shubham's answer a good place to handle all these redirects would be in a middleware. Generally its better to leave actions and reducers pure.
You can add a third field in your action object that could be as follows
export function loginSuccess() {
return {
type: 'types.LOG_IN_SUCCESS',
redirectAfter: '/path/you/wish/to/redirect/after/action'};
}
}
RedirectMiddleware.js
import history from '../history';
const redirectMiddleware = () => next => action => {
if (action.redirectBefore) { // Redirects to the route BEFORE dispatching action to reducers
history.push(action.redirectBefore);
}
const result = next(action);
if (action.redirectAfter) { // Redirects to the router AFTER dispatching action to reducers
history.push(action.redirectAfter);
}
return result;
};
export default redirectMiddleware;
In your store's config.js
add the middleware
applyMiddleware([redirectMiddleware])
So in your action you can pass redirectBefore as the path to which you want to redirect to before the action hits your reducer, or the redirectAfter if you want to redirect before the action is passed on to the reducers.
Upvotes: 1
Reputation: 281606
Since you are using HashRouter, you either can use history
from props like it is mentioned in Programmatically Navigate using react-router
or you need to create a history using createHashHistory
instead of createBrowserHistory
and pass it on to the generic Router component like
import { Router } from 'react-router-dom';
export const history = createHashHistory();
class App extends Component {
render() {
return (
<Router history={history}>
<Switch>
<Route path="/restaurant" name="Restaurant" component= .
{RestrauntDashboard} />
<Route path="/" name="Home" component={Home} />
</Switch>
</HashRouter>
);
}
}
Upvotes: 1