React router redirect after action redux

116,698

Solution 1

With React Router 2+, wherever you dispatch the action, you can call browserHistory.push() (or hashHistory.push() if that’s what you use):

import { browserHistory } from 'react-router'

// ...
this.props.dispatch(registerStep1Success())
browserHistory.push('/registrationStep2')

You can do this from async action creators too if that is what you use.

Solution 2

Have you checked out react-router-redux? This library makes it possible to sync react-router with redux.

Here is an example from the documentation of how you can implement the redirection with a push action from react-router-redux.

import { routerMiddleware, push } from 'react-router-redux'

// Apply the middleware to the store
const middleware = routerMiddleware(browserHistory)
const store = createStore(
  reducers,
  applyMiddleware(middleware)
)

// Dispatch from anywhere like normal.
store.dispatch(push('/foo'))

Solution 3

Simplest solution for router version 4+: We use "react-router-dom": "4.3.1" It doesn't work with version 5+

export your browser history from the place where it was initialised and use browserHistory.push('/pathToRedirect'):

Package history must be installed(example: "history": "4.7.2"):

npm install --save history

In my project I initialise browser history in index.js:

import { createBrowserHistory } from 'history';

export const browserHistory = createBrowserHistory();

Redirect in the action:

export const actionName = () => (dispatch) => {
    axios
            .post('URL', {body})
            .then(response => {
                // Process success code
                  dispatch(
                    {
                      type: ACTION_TYPE_NAME,
                      payload: payload
                    }
                  );
                }
            })
            .then(() => {
                browserHistory.push('/pathToRedirect')
            })
            .catch(err => {
                // Process error code
                    }
                );
            });
};

Solution 4

To build on Eni Arinde previous answer's (I don't have the reputation to comment), here is how to use the store.dispatch method after an async action :

export function myAction(data) {
    return (dispatch) => {
        dispatch({
            type: ACTION_TYPE,
            data,
        }).then((response) => {
            dispatch(push('/my_url'));
        });
    };
}

The trick is to do it in the action files and not in the reducers, since reducers should not have side effects.

Solution 5

An updated answer using hooks; for router v5 users.

Working on react-router-dom:5.1.2.

No installation of external package is required.

import { useHistory } from "react-router-dom";

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

You can use the history as you're previously used to.

More more details and APIs - read the manual

Share:
116,698

Related videos on Youtube

ximet
Author by

ximet

Updated on July 05, 2022

Comments

  • ximet
    ximet almost 2 years

    I'm using react-redux and react-router. I need to redirect after an action is dispatched.

    For example: I have registration a few steps. And after action:

    function registerStep1Success(object) {
        return {
            type: REGISTER_STEP1_SUCCESS,
            status: object.status
       };
    }
    

    I want to redirect to page with registrationStep2. How can I do this?

    p.s. In history browser '/registrationStep2' has not been visited. This page appears only after successful result registrationStep1 page.

  • ximet
    ximet over 8 years
    I know about it routing. But, I wonder is it possible to use standard react-routing
  • ximet
    ximet over 8 years
    And how redirect on the other page after Action (using react-router-redux).?
  • ximet
    ximet over 8 years
    what are the benefits using redux-router in future, which now in beta?
  • Dan Abramov
    Dan Abramov over 8 years
    If you ever want to have Redux DevTools replay routing transitions you’d need to choose between github.com/acdlite/redux-router and github.com/reactjs/react-router-redux. In this case I would recommend github.com/reactjs/react-router-redux because it is more stable and much simpler.
  • pedrommuller
    pedrommuller over 7 years
    @DanAbramov how can we do a redirect after an action as ximet is asking? is that correct to do a "push" in the reducer that handles REGISTER_STEP1_SUCCESS?
  • vasekhlav
    vasekhlav over 7 years
    Is this solution still available? I don't seem to be able to get this working... The URL updates after I use browserHistory.push() but the view does not.
  • vasekhlav
    vasekhlav over 7 years
    Nevermind, I got it working, I was using browserHistory.push() although my router used hashHistory. hashHistory.push() works like a charm.
  • Juni Brosas
    Juni Brosas over 7 years
    @vasekhlav Im glad I found your comment above. Use hashHistory if the store is using it.
  • Ante
    Ante about 7 years
    Can you access store inside reducer?
  • wintercounter
    wintercounter almost 7 years
    Even that this solution works, actions shouldn't be aware of routing at all IMO. You should be able to dispatch an action without any routing.
  • Jitin Maherchandani
    Jitin Maherchandani over 6 years
    Is this a right way to approach the problem? Should we pass history object from component to the action creator for routing?
  • Joerg
    Joerg over 6 years
    Does this still hold true for React Router 4+? Or is there now a better way to do this?
  • Nabarun
    Nabarun over 6 years
  • Artur
    Artur almost 6 years
    Tip: If you want to redirect (without pushing location to history) like <Redirect to="..." /> just use history.replace('/someroute').
  • Uj Corb
    Uj Corb over 5 years
    react-router-redux in now deprecated. Have a look instead at github.com/supasate/connected-react-router
  • Nour
    Nour over 5 years
    How could you chain dispatch calls? dispatch().then(()=>dispatch) ? It doesn't seem to work. 'then is not a function'
  • Radek Matěj
    Radek Matěj almost 5 years
    browserHistory no longer works, but there is a possibility to create your own history object and access it from anywhere.
  • Dimitar Veljanovski
    Dimitar Veljanovski about 4 years
    I know its for sake of example but you really shouldn't separate registration part 1 and 2 into 2 routes or 2 seperate forms unless you are doing it for the sake of email verification or some other purpose like that. Furthermore the browserHistory no longer works in new version of react, now they are suggesting to use the Redirect component which is extended from react-router-dom or the useHistory hook. I hate using hooks so i stick with Redirect and browserHistory when im working with older versions of react.
  • YanivGK
    YanivGK about 4 years
    It does change the url, but doesn't effects the 'react-router'. If you're using this module - I'll advice to look for a different solution.
  • YanivGK
    YanivGK about 4 years
    Could you please share the relevant imports, and the rest of the code?
  • Jackkobec
    Jackkobec about 4 years
    This solution still works perfectly, but there is a lot of other.
  • Jackkobec
    Jackkobec about 4 years
    Use "react-router-dom": "4+" for this solution. We use "react-router-dom": "4.3.1"
  • YanivGK
    YanivGK about 4 years
    I just tried that again, still won't work. I actually use "react-router-dom": "5.2.0", even though the url changes the browser won't surf to the required page. I think I might open a different question, this seems weird.
  • Jackkobec
    Jackkobec about 4 years
    This solution doesn't work with Router v5. Use "react-router-dom": "4+" for this solution. We use "react-router-dom": "4.3.1
  • azamsharp
    azamsharp over 3 years
    For me even the import { browserHistory } from 'react-router' is not working. 'browserHistory' is not exported from 'react-router'