Search code examples
reactjshttp-redirectroutersaga

react router history.push not loading expected component


I am using saga for managing my async call.

Here is login saga :

export function* loginApi({ type, formObj }) {
    const formData = new FormData();
    Object.keys(formObj).map(key => {
        formData.append(key, formObj[key]);
    })
    const response = yield axios.post(`http://localhost/coupon/web/api/login`, formData)
    if (response.data.status) {
        localStorage.setItem('token', response.data.data.token);
        yield put(loginsuccess(response.data.data.token))
        yield call(forwardTo, '/dashboard')
    } else {
        yield put(loginFaield(response.data.msg))
    }
}

After login successful I want redirect user to dashboard so for that:

yield call(forwardTo, '/dashboard') which execute forwardTo function and below is implementation of it:

import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
function forwardTo(location) {
    console.log('location', location);
    history.push(location);
}

export default forwardTo;

It change my url from http://localhost:3000/login to http://localhost:3000/dashboard but it shows login page instead of dashboard.

Routes :

const Routes = () => {
    return (
        <Switch>
            <Route path="/register" component={RegisterUser} />
            <Route path="/dashboard" component={Dashboard} />
            <Route path="/login" component={Login} />
            <Route path="/" component={Home} />
        </Switch>
    )
}

Solution

  • You can achieve this in the Login Component...

    After the saga does this yield put(loginsuccess(response.data.data.token)) Now I assume.. some data regarding login successful is stored. Say state.user.token is null before login, after login it has some value.

    Do 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.token ? 
          <Redirect to={'/dashboard'}/> : null
        }
        </div>
      ) 
    };
    
    const mapStateToProps = state => ({
        token: //state.user.token or whatever
    });
    
    export default compose(
        withRouter,
        connect(mapStateToProps, mapDispatchToProps)
    )(Login);
    

    When user is not logged in the token value is null so it renders nothing but when login is successful, some value assigned to token, as the result <Redirect to='/dashboard'/> will be rendered and the site will be redirected to /dashboard