首页 > 解决方案 > useSelector 函数没有更新调度函数后的状态 -react hooks

问题描述

我正在执行一个身份验证模块,当我单击登录按钮时,我正在验证用户是否存在 MySQL db。我在登录页面中调度功能

基本上,当我调度它时, rSignedIn 的 null 状态不会在调度函数之后立即更改。我完全使用反应钩子。请帮我解决这个问题,我已经尝试了三天。

但是当我再次单击登录按钮时 rSignedIn 状态值会更新,一般来说,当我使用 useSelector 使用状态值时,值会在调用 handleLogin() 时第二次更新

//Sign in Page

...
...

const status=useSelector((state)=>state);
...
...
const handleLogin=(event)=>{
      dispatch(LoginUser(loginData));
      console.log(status.auth.rSignedIn);
      if(status.auth.rSignedIn){
        console.log("LOGIN success");
        History.push('/');
      }else{
        console.log("LoginFailed") ;
      }
    }

这是我向 MySQL db 发送请求的操作索引页面,如果有响应,我将发送它,否则会出错。

export const LoginUser=(loginData)=>async(dispatch)=>{
    await mysqlDB.post('/fetch/retreive',loginData)
    .then((response)=>dispatch({type:ActionTypes.LOGIN_SUCCESS,payload:response.data}))
    .catch((error)=>dispatch({type:ActionTypes.LOGIN_FAILED}))
}

这是我的减速器:

const initialState = {
    gSignedIn:null,
    userId:null,
    registered:null,
    data:null,
    rSignedIn:null,
}


export default (state=initialState,action)=>{
    switch (action.type){
        case ActionTypes.GSIGN_IN:
            return {...state,gSignedIn:true,userId: action.payload};
        case ActionTypes.GSIGN_OUT:
            return {...state,gSignedIn:false,userId:null};
        case ActionTypes.REGISTER_SUCCESS:
            return {...state,registered:true,data: action.payload};
        case ActionTypes.REGISTER_FAILED:
            return {...state,registered:false,data:null};
        case ActionTypes.LOGIN_SUCCESS:
            return {...state,rSignedIn:true,data: action.payload};
        case ActionTypes.LOGIN_FAILED:
            return {...state,rSignedIn:false,data:null};
        case ActionTypes.LOGOUT:
            return {...state,rSignedIn:false,data:null};
        default:
            return state;
    }
};

标签: mysqlreactjsreduxreact-reduxreact-hooks

解决方案


dispatch不会立即更新您的状态值。状态值受闭包约束,只会在您的下一个渲染周期中更新。

您可以history.push在您的内部使用action或使用 useEffect

const handleLogin=(event)=>{
      dispatch(LoginUser(loginData, History));
    }

...

export const LoginUser=(loginData, history)=>async(dispatch)=>{
    await mysqlDB.post('/fetch/retreive',loginData)
    .then((response)=>{
           dispatch({type:ActionTypes.LOGIN_SUCCESS,payload:response.data}));
           history.push('/')
    }
    .catch((error)=>{
          dispatch({type:ActionTypes.LOGIN_FAILED}))
    }
}

使用 useEffect,您只需要在更改时运行它,而不是在初始渲染时运行

const initialRender = useRef(true);
useEffect(() => {
   if(!initialRender.current) {
       if(state.auth.rSignedIn) {
           history.push('/');
        } else {
           console.log(not signed in);
        }
   } else {
       initialRender.current = false;
   }
}, [state.auth.rSignedIn])

推荐阅读