尽管收到有效的Action Payload(Async Auth Call),为什么我的Redux State没有更新

时间:2018-01-11 00:40:04

标签: javascript reactjs authentication asynchronous redux

我正在使用Redux,并将Redux Thunk Fetch Call调度到RESTful API以验证Login Credentials。 API在响应中成功返回JWT(授权令牌)。

我的Reducer配置为使用此令牌更新Store,但它返回“undefined”而不是Token。我可以在Redux Logger Action Payload中看到令牌 - 所以我不确定发生了什么。

我怀疑这是因为API没有足够快地发送令牌,而我的Reducer正在使用未解析的值进行更新。日志确实暗示了这一点,但我也很困惑为什么 - 当我在console.log中打开动作时,Promise的状态从挂起到同一条目内的履行波动!

我将发布我的Action + Reducer代码和相关的控制台日志 - 如果有人能指出我错误的正确方向,我将非常感激:

/// REDUCERS

const initialState = { isAuthenticated: false}
const authReducer = (state = initialState, action) => {
    switch(action.type){
    case ('USER_AUTHENTICATED'): { 
        return Object.assign({}, state, {
            isAuthenticated: true,
            token: action.userInfo.token,
        }
        )
    }
    case ('INVALID_CREDENTIALS'): { 
        return Object.assign({}, state, {
            isAuthenticated:false
            }
        ) 
    }
    default:
            return state

}

/// ACTIONS

function authSuccess (userInfo) {
    return {
    type:'USER_AUTHENTICATED',
    userInfo
    }    
}     
function authFail () {
    return {
    type: 'INVALID_CREDENTIALS'
    }
}

export function attemptLogIn(credentials) {
    return dispatch => {
        return fetch('http://localhost:3001/authorize', {
        headers:{
            'Content-Type': 'application/json'
        },
        method: 'POST',
        mode: 'cors', 
        body: JSON.stringify(credentials)
        })
        .then(response => response.ok ? dispatch(authSuccess(response.json())) : dispatch(authFail()))
    }
}

最初,Redux Logs将Action视为待定承诺:

enter image description here

令牌“未定义”反映了这一点 enter image description here

然而,当我打开相同的动作时,我可以清楚地看到Promise的状态已经变为分辨率,并且令牌实际上就在那里。

enter image description here

我认为authSuccess()调度只会在收到(response.ok)之后触发 - 那么Promise如何仍然待定?

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

原因是您要发送reponse.json(),它自己会返回promise

此外,您需要将json结果从fetch传递回authSuccess动作创建者

将代码更改为:

.then(response => response.ok ?  response.json() : throw new Error(response.statusText))
.then(json => dispatch(authSuccess(json))
.catch(err => dispatch(authFail()))