I'm trying to redirect user to '/' route in my redux action. But I can see that the route in the browser is changing but component does not render (it stays at the same view).

My action looks like that:

import history from '../../history';

export const logoutUser = () => dispatch => {
  api.logout();
  // redirect
  history.push('/');

  dispatch({ type: TYPES.LOGOUT_USER });
};

My component with routes looks like that:

import React, { Component, Fragment } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import history from './history';
import { Landing, AnotherComponent } from './views';


class App extends Component {
  render() {
    return (
      <Fragment>
        <Router history={history}>
          <div className="main-container">
            <Route exact path="/" component={Landing} />
            <Route path="/another_route" component={AnotherComponent} />
          </div>
        </Router>
      </Fragment>
    );
  }
}

export default App;

And history.js file:

import createHistory from 'history/createBrowserHistory';

export default createHistory();

Thanks for helping!

4 Answers

0
UjinT34 On

BrowserRouter doesn't support history property. Try using the history object provided by react-router. Anything rendered directly from Route gets it as a property. For a deeply nested component you can use withRouter HOC. You will have to pass this history object to logoutUser.

Sample code from the documentation.

0
SakoBu On

If you're using history import Router not BrowserRouter from the lib... Something like this:

import React, { Component } from 'react';
import { Router, Route, Switch } from 'react-router-dom';

import history from './history';
import { Landing, AnotherComponent } from './views';

class App extends Component {
  render() {
    return (
      <Router history={history}>
        <Switch>
          <div className="main-container">
            <Route exact path="/" component={Landing} />
            <Route path="/another_route" component={AnotherComponent} />
          </div>
        </Switch>
      </Router>
    );
  }
}

export default App;
0
Lee O. On

If you use withRouter from react-router-dom in your component that triggers the logout call, you can pass the history to your action through the ownProps of mapDispatchToProps. Here is an example from one of my apps.

Component:

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    createTraining: training => dispatch(createTraining(training, ownProps)),
  };
};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(TrainingDetailsPage));

My Thunk:

export function createTraining(training, ownProps) {
  return function(dispatch) {
    return Api.createTraining(training).then(response => {
      ownProps.history.push('/trainings');
    });
  };
}
-1
Evan liu On

I am writing an new framework for react + redux + router v4 and saga (pengding), you can check from here step by step: https://github.com/liuxiaocong/react-base2019/blob/master/README.md