加载状态永不为真?(反应-Redux)

时间:2020-08-04 06:50:46

标签: javascript reactjs redux

我正在创建一个应用程序,该应用程序在用户登录时从后端获取用户数据并将其显示在用户个人资料中,我需要设置 loading...之类的加载语句来代替个人资料,然后再从所有数据中获取数据后端然后改为显示数据

我的动作创作者:

export const loginUser = (loginData) => (dispatch) => {

    axios.post('/signin', loginData)
        .then(res => {
            let FBIdToken = `Bearer ${token}`;
            localStorage.setItem('FBIdToken', FBIdToken);
            dispatch(getUserData());
        })
        .catch(err => {
            dispatch({
                type: SET_ERRORS,
                payload: err.response && err.response.data
            });
        });
}

export const getUserData = () => dispatch => {
    dispatch({ type: LOADING_USER });

    axios.get('/user')
        .then(res => {
            dispatch({
                type: SET_USER,
                payload: res.data
            })
        })
        .catch(err => console.log(err))
}

减速器:

const intialState = {
    authenticated: false,
    loading: false,
    credentials: {},
};

export default (state = intialState, action) => {
    switch (action.type) {
        case SET_USER:
            return {
                authenticated: true,
                loading: false,
                ...action.payload,
            }
            case LOADING_USER:
                return {
                    loading: true,
                    ...state
                }

        default:
            return state;
    }
};

登录页面:

    const handleSubmit = (e) => {  
        e.preventDefault();
        loginUser(loginData);
    }

现在,当我单击登录页面handlesubmit功能上的提交按钮时,运行loginUser操作创建者,而角色运行getUserData操作创建者。

现在在getUserData操作创建者中,将分派该操作{type: LOADING_USER},并且应该在userData来自后端之前从reducer返回此状态:

{
  loading: true,
  credentials: {},
  authenticated: false
}

,然后数据在axios请求之后出现,并将loading更改为false并设置用户凭据,但是在我的情况下不是这种情况,因为加载永远不会在我的代码中实现loading...永远不会在设置为用户个人资料的用户凭据之前显示。我的代码有什么问题?

2 个答案:

答案 0 :(得分:2)

正如我在上面的评论中提到的,您需要切换loading: true...state的顺序。

原因:(您猜对了),在展开对象时,顺序很重要,尤其是在所展开的对象中还包含loading键的情况下。因此,如果在...state之后保留loading: true,它将用loading: truestate具有的任何值覆盖loading。我想那不是我们想要的。因此,请将...state放在loading: true之前,以获得预期的结果。

答案 1 :(得分:2)

您在当前更新状态之后传播先前状态:

case LOADING_USER:
  return {
    loading: true,
    ...state
  }

您需要做相反的事情:

case LOADING_USER:
   return {
     ...state,
     loading: true,              
   }

通过在加载后扩展状态,您以前的状态将覆盖新状态,但是通过首先扩展前一个状态,您将仅覆盖状态的加载部分!