Graham
Graham

Reputation: 4285

Dispatch action in response to another action

I'm setting up redux in my app, and am starting with log in. So far I've got it working great - user logs in using Google, on success my server returns an access token to the web app that is put into the redux store, and can then be used for future API calls.

What I would like is for the webapp to immediately request the current users profile in response to storing the access token. It needs to be after the access token is stored though - so after the reducer is called.

In essence, in response to the AUTHENTICATED action, I'd like to dispatch the LOAD_USER action - which itself is promise based, so the LOAD_USER_RESOLVED action then eventually gets triggered to store the newly logged in user into the store, which will then display their name in the UI.

I'm using redux-promise-simple at the moment, but if that needs to change there not a problem.

Upvotes: 2

Views: 2023

Answers (1)

Yo Wakita
Yo Wakita

Reputation: 5440

When I usually need to chain something like authentication actions, I put some logic in a connected login component. I would set a boolean that would change from false to true in my AUTHENTICATED redux action. And have the component listen to that value. When the value were to change to true, I would fire off the second action.

Example:

    // Auth reducer
export const authentication = (
  state = {
    authenticated: false,
    identity: null,
    token: null,
    loading: false,
  },
  action,
) => {
  switch (action.type) {
    case types.LOGIN:
      return {
        ...state,
      };
    case types.AUTHENTICATED:
      return {
        ...state,
        authenticated: true,
        token: action.result.data,
      };
    case types.LOAD_USER:
      return {
        ...state,
        loading: true,
      }
    case types.LOADED_USER:
      return {
        ...state,
        loading: false,
        identity: action.result.data
      }
    default: return state;
  }
}


//Connected component:
import { loadUser } from 'actions';

class Login extends React.Component {

  componentWillMount() {
    const { token, authenticated } = this.props;
    if (authenticated && token ) {
      // Dispatch your action here;
      loadUser(token);
    }
  }
  componentWillReceiveProps(nextProps) {
    const { token, authenticated } = nextProps;
    const { loadUser } = this.props;
    if (authenticated && token ) {
      // Dispatch your action here;
      loadUser(token);
    }
  }
  ...

  ...

  mapStateToProps(state) {
    const { token, authenticated } = state.authentication
    return {
      authenticated,
      token
    }
  }

  export default connect(mapStateToProps, { loadUser })(Login)

Edit: If you would rather chain actions together rather than have a component listen on the redux store to dispatch an action. Take a look at the redux-thunk library here, it is a useful thunk middleware, and has some really useful examples of chaining async actions there.

Upvotes: 1

Related Questions