Call function after dispatch from redux has finished

33,798

Solution 1

Have your action creator return a promise. This way when you invoke it, you can use .then() and in your then handler you can push a new address to the history.

Thunks will return functions normally, but a promise differs in that you can act after completion.

Example:

static myActionCreator(somevar) {
  return dispatch => {
    return new Promise((resolve, reject) => {
      dispatch({
        type: "myaction",
        something: somevar
      });

      resolve()
    });
  }
}

So in this case, your thunk returns a promise. Then when you invoke like this:

this.props.myActionCreator(somevar)
.then(() => {
  this.props.history.push('/winning')
})

This thunk is just dispatching an action, but you could have some async call in there that has a callback, etc. and you resolve on completion.

Solution 2

I think what you are looking for is Redux Saga.

You can use the TakeEvery Effect, which will trigger the function you want every time a specific action is called.

Example :

import { takeEvery } from `redux-saga/effects`

function* fetchUser(action) {
  ...
}

function* watchFetchUser() {
  yield takeEvery('USER_REQUESTED', fetchUser)
}

Take a look at the doc and read this article

Solution 3

I had similar confusion and ended up spending quite a time working on solving the problem through callbacks and javascript promises which is not required at all because of react-redux setup.

this.props.clearReducersState()
this.props.history.push('/dashboard')

I was trying to go to my dashboard after my clearReducerState() function is dispatched. This code works just fine.

You need to do nothing react-redux works on a synchronous way, so you can simply do this. You can use history.push in your action too for that,

import { withRouter } from 'react-router-dom';
this.props.clearReducersState(this.props.history)

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(UpdateAid))

And in your action,

export const clearReducersState = (history) => dispatch => {
history.push('/dashboard')
}

However, if you are updating your state using reducers it is better to use history.push in your index file to avoid problems.

Use as per your requirement. Hope this helps.

Share:
33,798
KellysOnTop23
Author by

KellysOnTop23

Updated on August 28, 2021

Comments

  • KellysOnTop23
    KellysOnTop23 over 2 years

    All around it but not quite as I have enough of an idea of redux-thunk and of react-router but I am not getting this seemingly simple idea of:

    Call a change in route programmatically via <Route/>'s history.push('/') after an action has finished dispatching to the store, this to happen when a button is pushed.

    const LoggerRedux = ({stateProp, LogIn}) => {
        return(
          <div>
            <h2>Here is the button. Use this to login</h2>
            <Route render={({ history}) => (
              <button
                type='button'
                onClick={
    
                //Something that calls {LogIn}
                //and then the history.push('/')
    
                }
                >
                Log yo Arse Inn
              </button>
            )}>
    
            </Route>
          </div>
        )
    }
    
    const mapStateToProps = (state) => {
      return {
        stateProp : state
      }
    }
    const mapDispatchToProps = (dispatch) => {
      return {
        LogIn : () => dispatch({
          type : 'AUTHENTICATE'
        }),
        LogOut : (bool) => dispatch({
          type : 'LOGGED_OUT',
          bool
        })
      }
    }
    const LoginConn = connect( mapStateToProps, mapDispatchToProps)(LoggerRedux);
    

    Layman explanations and examples of all things I mentioned/tagged would also be nice