Handling promises / callbacks in the Redux store

I am currently using action creators with Redux to dispatch user actions (such as fetching account information). These action creators return promises from an API request that, when they resolve, updates the store.

The problem I'm running into is that I want to "intercept" certain API responses, in my case, an invalid JWT token. In such cases, I want to keep the pending promise, request a login modem, and if the login is successful, try again and resolve the promise.

It is enough for me to check the response after the call fetch

like this:

Root.js - Place a modal component in the DOM

export default (props) => {
    return (
        <div>
            <Modal />
            <App />
        </div>
    )
}

      

Modal.js - handle different modal types (Approach accepted by this post )

const MODALS = {
    LOGIN: LoginModal
}

const ModalRoot = ({type, props}) => {
    if (!MODALS[type]) return null;

    return <Modal {...props} />;
}

export default connect(
    state => state.modal
)(ModalRoot);

      

reducer.js - Modal reducer

const initialState = {type: null, props: {}}
export default function modal(state = initialState, action) {
    switch (action.type) {
        case 'SHOW_MODAL':
            return Object.assign({}, state, {
                type: action.modalType,
                props: {...action.props}
            });
        case 'HIDE_MODAL':
            return initialState;
        default:
            return state;
    }
}

      

actions.js - return a promise to receive a call

const promptLogin = () => (dispatch, getState) => {
    return new Promise((resolve, reject) => {
        return dispatch(showModal('LOGIN', {
            successCallback: (user) => resolve(user)
        }));
    })
}

      

makeAPIRequest.js - make an API call, handle an invalid token

fetch(endpoint, requestConfig)
    .then(res => res.json())
    .then(data => {

        /** Invalid JWT Token */
        if (data && data.error_code === 403) {
            return store.dispatch(promptLogin())
                .then(token => {
                    return makeRequest(method, endpoint, headers, body)
                });
        }

        return data;
    });

      

The problem with this approach is that I keep the callback function (to complete the original request) in the store, which is not recommended in the redux docs.

If my Modal component is not connected to my fetch logic, and I cannot keep the Promise or callback in state (because they are not serializable), how can I continue the promise from the original request after the user logs in from the modal?

+3


source to share





All Articles