useSelector 函数没有更新调度函数后的状态 -react hooks

Posted

技术标签:

【中文标题】useSelector 函数没有更新调度函数后的状态 -react hooks【英文标题】:useSelector function is not updating the state of after dispatch function -react hooks 【发布时间】:2020-09-06 14:42:58 【问题描述】:

我正在执行一个身份验证模块,当我单击登录按钮时,我正在验证用户是否是 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;
    
;

【问题讨论】:

【参考方案1】:

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

您可以在 action 中使用 history.push 或使用 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])

【讨论】:

但是如果我想在同一个页面中渲染状态值呢?而且正如你所说的使用 useEffect 一旦我使用过,当我点击登录页面时它会重定向到主页它没有进入登录页面,useEffect 的使用不允许我进入登录页面,可能是我的语法错误,请你帮我解决这个 useEffect 函数。 您可以在返回部分回复要更新的状态值,以便您进行渲染。只是不要在期望它被更新的同一个函数中使用它 但是如果我想在同一个页面中渲染状态值呢?而且正如你所说的使用 useEffect 一旦我使用过,当我点击登录页面时它会重定向到主页它没有进入登录页面,useEffect 的使用不允许我进入登录页面,可能是我的语法错误,你能帮我使用那个 useEffect 函数吗 用你将如何使用 useEffect 更新了我的帖子

以上是关于useSelector 函数没有更新调度函数后的状态 -react hooks的主要内容,如果未能解决你的问题,请参考以下文章

useSelector 在调度后定义但随后未定义

Redux 存储在调度后不更新(异步数据加载)

深度剖析 Vue3 的调度系统

是否可以为 useSelector 创建一个可重用的函数?

React hook useSelector 值在异步函数中未更改

在我的权限上下文提供程序的函数错误中调用了 React 钩子“useSelector”