Search code examples
reduxredux-thunk

Share actions between domains


Usually I use redux-saga, but currently I need redux-thunk. I'm using ducks for modular structure and now for example I have two ducks: auth and user with async actions below:

auth-duck.js

register(credentials) {
    return dispatch => {
        dispatch(actions.registerRequest());
        return service.requestRegister(credentials)
            .then((response) => {
                dispatch(actions.registerSuccess(...));

                // Here I need to dispatch some action from user-duck.js
            })
            .catch(() => dispatch(actions.registerError(...)))
    }
}

user-duck.js

fetchUser() {
    return dispatch => {...}
}

I really don't know how to not mess these two modules and dispatch fetchUser after successful register.

I could return register result (e.g. token or something else) to container from here it was dispatched and then using chaining dispatch fetchUser.

AuthContainer.js

_onSubmit() {
    this.props.register().then(() => this.props.fetchUser);
}

But I don't know is it the best way to manage such operations with redux-thunk?


Solution

  • After a long search I found two options how to share the logic from separate domains. The first one is to use mapDispatchToProps (Thanks @DonovanM), just like this:

    function mapDispatchToProps(dispatch) {
       return {
           login: (credentials) => {
               return dispatch(authActions.login(credentials)).then(
                   () => dispatch(userActions.fetchUser())
               );
           }
       }
    }
    

    login function returns Promise thats why we can chain it to another one.

    And the second possible option: Use something like a "bridge" file in our case it is app-sagas.js

    app-duck.js

    import {actions as authActions} from './auth-duck.js';
    import {actions as userActions} from './user-duck.js';
    
    export function doLogin(credentials) {
        return dispatch => {
            return dispatch(authAction.login(credentials)).then(
                () => dispatch(userActions.fetchUser())
            );
        }
    }
    

    In the second case we can place all logic into ducks and avoid spreading the logic within containers. But I guess it is possible to combine both methods.