1

I'm using react-thunk with redux to implement a login function, but when I access the state using getState(), the property returns undefined.

SystemState will set IsLogined and user when LoginSuccessed, I will use it later on for access token. But when I try to implement a logout function, getState().Property returns undefined

function logout() : ThunkAction<void, SystemState, null, Action<string>> {
    return async (dispatch, getState) => {
        const { user, isLogined } = getState();

        console.log(`user: ${user} isLogined:${isLogined}` )
        // Console writes user: undefined isLogined: undefined

        if (!isLogined) {
            dispatch(actions.LogoutFailed("No login Session Found"));
        } else if (user) {
            const result = await services.Logout(user.UserId);

            if (result.errorMessage) {
                dispatch(actions.LogoutFailed(result.errorMessage));
            } else {
                dispatch(actions.Logout());
            }
        }
    }
}

Did getState() should not be called inside an async function?

--- edit ---

Reducer for SystemSate

const initState = {    
    isLogined: false
}

function SystemStateReducer(state = initState, action) {
    switch(action.type) {
        case types.LOGIN_SUCCESS:            
            return {
                ...state,
                isLogined: true, 
                user: action.user, 
                errorMessage: undefined
            }
        case types.LOGIN_FAILED:
            return {
                ...state, 
                isLogined: false, 
                user: undefined, 
                errorMessage: action.errorMessage
            }
        case types.LOGOUT_SUCCESS:
            return {
                ...state,
                isLogined: false, 
                user: undefined, 
                errorMessage: undefined
            }
        case types.LOGOUT_FAILED:
            return {
                ...state,                 
                isLogined: false, 
                user: undefined,
                errorMessage: action.errorMessage
            }
        default:
            return state;
    }
}

CombineReducer

const rootReducer = combineReducers({
    systemState
});
Ray Tang
  • 55
  • 1
  • 9

1 Answers1

0

The issue is you're misinterpreting what the state structure will be.

You've defined your root reducer as:

const rootReducer = combineReducers({
    systemState
});

The systemState reducer, in turn, has an initial state of:

const initState = {    
    isLogined: false
}

Those two things define the structure of what is returned by getState(), which will actually be:

{
    systemState : {
        isLogined : true
    }
}

Note that this means you need state.systemState.isLogined, not state.isLogined.

So, in your case, what you probably want is:

const state = getState();
const {isLogined} = state.systemState;
markerikson
  • 42,022
  • 7
  • 87
  • 109
  • Thanks. I have updated my code according to your suggestions, and it turns out my `ThunkAction` did not use the correct `StateStore`, should use the global one `AppStateStore` , instead of individual ones `SystemState`. – Ray Tang Apr 10 '19 at 09:23