Search code examples
reactjsreduxreact-reduxreducers

Accessing a reducer state from within another reducer


I have a reducer whereby I am retuning the appropriate state when an action is dispatched. Now I am calling an API at regular intervals so the result will trigger an action again and again. So what I want is that if the reducer state already has data then another reducer doesn't show the state as loading while the call is sent. It must maintain its loading state when receiving data the first time only. I hope I am able to explain it properly

Here are my code snippets

Loading state reducer

const loading = (state = false, action) => {

    switch (action.type) {
    case 'GET_AUDIT_DATA':         // here I want to return true only when there is no data available
        return true
    case 'GET_AUDIT_DATA_RECEIVED':  
        return false
    case 'GET_AUDIT_DATA_ERROR':
        return false
    default:
        return state
    }
}

Combining reducers

const allReducers = combineReducers({
    auditData: AuditData,
    auditLoading: AuditLoading,
    modifiedOrders: ModifiedOrders
});

export default allReducers;

Reducer returning data on action triggered by superagent

const auditData = (state = [], action) => {
    switch(action.type) {
        case 'GET_AUDIT_DATA_RECEIVED': 
        console.log(action.data);
            return action.data;
        case 'GET_AUDIT_DATA_ERROR': 
            return action.err;
        default :
            return state;
    }
}
export default auditData;

So initially the auditData doesn't contain any data, only after the first success call it returns the data. When this is called at the same time loading state reducer is called and it should return true in GET_AUDIT_DATA action only when the audit data reducer doesn't contain any data.

Also is returning just the current obtained data from auditData the right way to go or I should do it differently. Basically I want to overwrite the current data with the new one.


Solution

  • The best way to proceed is to send to Loading state reducer an information to know if the other reducer already have data. To have at the end:

    const loading = (state = false, action) => {
    
        switch (action.type) {
        case 'GET_AUDIT_DATA':
            if(!action.dataAlreadyInitialized){
                return true
            }
        case 'GET_AUDIT_DATA_RECEIVED':  
            return false
        case 'GET_AUDIT_DATA_ERROR':
            return false
        default:
            return state
        }
    }
    

    You should have access from your action function to the application state and do:

    dispatch({
      type:'GET_AUDIT_DATA',
      dataAlreadyInitialized: appState.auditData.length > 0
    });