grazdev
grazdev

Reputation: 1282

Action payload is being used twice (Redux)

I am creating a server-side rendered React app that uses Redux and fetches content from a Wordpress installation (through the WP API). Please consider the following reducer:

const initState = {
    mainMenu: null,
    userMenu: null
}

export default ( state = initState, action ) => {

    switch( action.type ) {

        case 'FETCH_MAIN_MENU':
            state = {
                ...state, 
                mainMenu: action.payload.data
            }           

        case 'FETCH_USER_MENU':
            state = {
                ...state, 
                userMenu: action.payload.data
            }                   

        default: 
            return state; 

    }

}

Both actions are dispatched on the server side, before the app is rendered for the first time, and both actions are promises that return two different menus. The problem is that sometimes the payload for FETCH_USER_MENU is actually the same as the payload for FETCH_MAIN_MENU. Presumably, this happens when the promise issued by FETCH_USER_MENU resolves too slowly, and thus action.payload.data takes the value assigned to it in the FETCH_MAIN_MENU case. I'm pretty sure this is what's going on because if I arbitrarily set action.payload.data to null, the user menu (again, only sometimes) isn't rendered at all:

const initState = {
    mainMenu: null,
    userMenu: null
}

export default ( state = initState, action ) => {

    switch( action.type ) {

        case 'FETCH_MAIN_MENU':
            state = {
                ...state, 
                mainMenu: action.payload.data
            }           

        action.payload.data = null; 

        case 'FETCH_USER_MENU':
            state = {
                ...state, 
                userMenu: action.payload.data // Sometimes results as null
            }                   

        default: 
            return state; 

    }

}

Can you suggest a solution other than creating a different reducer for each menu, which I would like to avoid?

Upvotes: 0

Views: 269

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281804

The problem is caused by Switch case fallthrough since you are not returning from the case statement nor using break. Ideally with redux you need to return the updated state. Your would write

export default ( state = initState, action ) => {

    switch( action.type ) {

        case 'FETCH_MAIN_MENU':
            return {
                ...state, 
                mainMenu: action.payload.data
            }           

        case 'FETCH_USER_MENU':
            return  {
                ...state, 
                userMenu: action.payload.data
            }                   

        default: 
            return state; 

    }

}

Upvotes: 2

Related Questions