2

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

Mickael Zana
  • 170
  • 2
  • 3
  • 16

3 Answers3

1

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>
   );
 }
}
Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
  • i already create it in my index.js but that is don't work , i am in this url http://localhost:3000/#/login and when i click on the login button they redirect me to http://localhost:3000/restaurant#/home i don't know why – Mickael Zana Jun 18 '18 at 15:58
  • You are using createBrowserHistory, use createHashHistory. Also Router needs to change to use custom history – Shubham Khatri Jun 18 '18 at 16:00
1

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.

johnny peter
  • 3,155
  • 21
  • 35
0

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!

p2pdops
  • 114
  • 5