Redux thunk actions and sharing state

487 Views Asked by At

I would like my application to be aware of when async actions are fired and when they complete. The reason for this is that I would like an overall loading state for my applications which sets to true when all async actions have completed. An early implementation of this used a global counter for callbacks.

These actions could be in different files and be listened to by separate reducers, responsible for different branches of state.

I'm using thunk-middleware combined with redux-promise-middleware so one of my async actions might look like this:

export const requestSiteData = () => (dispatch, getState, api) => {
  const url = '/endpoint';

  return dispatch({
    type: 'STATE_BRANCH/REQUEST_SOME_DATA',
    payload: api.fetch(url)
  }).catch(() => {});
};

This would then dispatch STATE_BRANCH/REQUEST_SOME_DATA_FULFILLED or STATE_BRANCH/REQUEST_SOME_DATA_REJECTED when complete.

Because of the promise middleware I'm finding it hard to intercept the call and count/determine how many ajax requests have been made and how many have completed because the actions are pre-determined and I can't dispatch another action from my reducers.

I can update state there obviously but the async actions may be split across several parts of the state tree so I don't have an overall place to manage the requests.

Does anyone have any ideas how I might go about solving this type of problem. Shout if the description/use case isn't clear.

2

There are 2 best solutions below

1
On

A thunk is a chain of function that executes one by one so in your case your code for async call should be

export function asyncAction() {
    return function(dispatch){
        fetchCall().then((data)=>data.json())
           .then((data)=>disptach(handleAsyncDataAction(data))
    }

and fetchCall() function should be write as.

function fetchCall(){
     return fetch('your_url');
}

and your handleAsyncData(data) action will return the result to the reducers so at the end for one fetch call you have to write 3 methods.

1. function you will call from Component

export function asyncAction(){..}

2. function who will written promise to this function

function fetchCall(){...}

3. and last function which will return handle return data and send it to reducer.

function handleAsyncData(data){....}
1
On

There is a Redux middleware based around redux-promise that will help you keep track of pending actions:

redux-pending