Murakami
Murakami

Reputation: 3760

Redirect in redux action using react-router-dom v4

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!

Upvotes: 1

Views: 4743

Answers (4)

DrSalas
DrSalas

Reputation: 1

Since I have not enough rep to vote or comment, I just wanted to say that the answer provided by Lee O. works perfectly fine. I am using [email protected] with .

I just wanted to add one detail. You don't need to add the withRouter and the connect when exporting the component if the component in question is already inside a parent component that uses them.

Upvotes: 0

Lee O.
Lee O.

Reputation: 3312

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');
    });
  };
}

Upvotes: 1

SakoBu
SakoBu

Reputation: 4011

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;

Upvotes: 0

UjinT34
UjinT34

Reputation: 4977

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.

Upvotes: 0

Related Questions