Search code examples
reactjsreact-routerreact-router-v4react-router-reduxconnected-react-router

reactjs: connected-router is not redirecting the user after push call is made


I would like my saga to redirect a logging in user to a main dashboard screen after successful authentication. I followed the code outlined in the following article: https://github.com/supasate/connected-react-router and example from https://github.com/supasate/connected-react-router/tree/master/examples/basic. I can see the url change when the push command is called from within the saga, however, the page is not redirecting to the dashboard screen. Instead, the user just stays on the same screen. I am currently running react-redux v6, react v16.4.1, react-router: v4.3.1, react-router-redux v4.0.8. What could I be doing wrong?

app.js:

class App extends Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      loaded: false
    }
  }

  componentDidMount() {
    window.addEventListener('load', () => {
      this.setState({loading: false});
      setTimeout(() => this.setState({loaded: true}), 500);
    });
  }

  render() {
    const loaded = this.state.loaded;
    const {history} = this.props;
    return (
      <div>
        {!loaded && <div className={`load${this.state.loading ? '' : ' loaded'}`}>
          <div className='load__icon-wrap'>
            <svg className='load__icon'>
              <path fill='#4ce1b6' d='M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z'/>
            </svg>
          </div>
        </div>}
        <div>
          <ConnectedRouter history={history}>
            <Router/>
          </ConnectedRouter>
        </div>
      </div>
    )
  }
}

history.js:

import { createBrowserHistory } from 'history';

export default createBrowserHistory;

store.js:

import {createStore, applyMiddleware} from 'redux';
import {reducer as reduxFormReducer} from 'redux-form';
import createSagaMiddleware from 'redux-saga';
import sagas from '../redux/sagas';
import reducers from '../redux/reducers';
import { createBrowserHistory,  } from 'history';
import { routerMiddleware } from 'connected-react-router';

const history = createBrowserHistory({ basename: '/myrootpath' });

const sagaMiddleware = createSagaMiddleware();

const store = createStore(reducers(history), applyMiddleware(routerMiddleware(history), sagaMiddleware));

store.runSaga = sagaMiddleware.run(sagas);
// store.asyncReducers = {};
const action = type => store.dispatch({type })

export default store;

index.js

import React from 'react';
import App from './app/App';
import {render} from 'react-dom'
import {Provider} from 'react-redux'
import {BrowserRouter} from 'react-router-dom';
import store from './app/store';
import ScrollToTop from './app/ScrollToTop';
import { createBrowserHistory } from 'history';

const history = createBrowserHistory()

render(
  <Provider store={store}>
      <BrowserRouter basename='/myrootpath'>
          <ScrollToTop>
              <App history={history}/>
          </ScrollToTop>
      </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);

saga code:

function* login(params){
try {
    const api = new UserApi();
    const {username, password} = params.login;
    const user = yield call(api.login, {username, password});
    debugger;
    yield put(push('/dashboard_default'));
} catch (error) {
    debugger;
    yield put({ type: types.LOAD_ERROR, error });
}
}

Solution

  • The same history object needs to be used in both places, e.g. in history.js:

    export default createBrowserHistory({basename: '/myrootpath'});
    

    and in index.js and store.js:

    import history from './history';