为啥 redux 只在浏览器刷新时更新?

Posted

技术标签:

【中文标题】为啥 redux 只在浏览器刷新时更新?【英文标题】:Why does redux only update on browser refresh?为什么 redux 只在浏览器刷新时更新? 【发布时间】:2021-09-22 00:46:53 【问题描述】:

我已经研究了很长时间了。我已经以各种可能的方式移动了东西。在搜索溢出后,我无法从其他用户提出的任何其他问题中找到解决方案。

我有一个允许用户登录的应用程序。我正在使用 redux 在用户登录后存储他们的凭据以接收他们的 JWT。我希望能够登录并立即看到自己已登录。但这仅在我刷新浏览器后登录后才会发生。

所以在反应中,我有一个登录表单,它在完成收集用户信息(登录名和密码)的所有典型功能后调用下面的函数。请注意,即使我实际上并没有使用它,我也需要在那里调度,否则我会收到一条错误消息,说“动作必须是普通对象”。

在该承诺结束时,我调用 getUser 获取该 JWT 并从服务器返回该帐户上的所有信息。在调试器中,它运行 login 函数,然后运行 ​​getUser 函数,但似乎永远不会将它存储在 redux 中,除非我刷新浏览器。

export const loginUser = (credentials) => dispatch => 
    axios.post('api_call', credentials)
        .then(res => 
            debugger;
            const token = res.data.token;
            localStorage.setItem('token', token);
            alert("You have logged in successfully!");
            getUser(token);
        );

export const getUser = (token) => dispatch => 
    debugger;
    axios.get('api_call', 
        headers: "Authorization" : `Bearer $token`
    ).then(user => dispatch(
            type: GET_USER,
            payload: [user.data]
        ));   

让我也给你看看我的减速器:

import  LOGIN_USER, REGISTER_USER, GET_USER, LOGOUT_USER  from "../actions/types";

const initialState = 
    items: []


export default function(state = initialState, action)
    switch(action.type)
        case REGISTER_USER:
            return
                ...state,
                items: action.payload
            ;
        // case LOGIN_USER:
        //     return
        //         ...state,
        //         items: action.payload
        //     ;
        case GET_USER:
            debugger;
            return
                ...state,
                items: action.payload
            ;
        case LOGOUT_USER:
            return
                ...state,
                items: []
            
        default:
            return state;
    

我已将 LOGIN_USER 注释掉,因为我意识到我实际上并没有向商店发送任何东西,而是只是将 JWT 保存到本地存储。

我还要提一下我的尝试。我想也许 getUser 无法以我尝试过的方式被调用。因此,在重定向到主页的导航链接上,我尝试将 getUser 调用放在那里。我尝试将 getUser 放在 Home 组件上的 useEffect 挂钩中以模仿 componentDidMount。我尝试在实际登录表单中调用 loginUser 后直接调用 getUser。由于异步,这不起作用(那时本地存储还没有 jwt)。我尝试更换减速器的部件。

这是我的 root reducer 和 store。 Auth reducer 适用于所有登录、注销和注册功能。

import  combineReducers  from "redux";
import showReducer from './showReducer';
import gearReducer from './gearReducer';
import authReducer from './authReducer';
import musicReducer from './musicReducer';
import profileReducer from './profileReducer';
import bagReducer from './bagReducer';

export default combineReducers(
    shows: showReducer,
    gear: gearReducer,
    auth: authReducer,
    music: musicReducer,
    profile: profileReducer,
    bag: bagReducer
);
import  createStore, applyMiddleware, compose  from "redux";
import thunk from 'redux-thunk';
import rootReducer from './reducers/rootReducer';
import  composeWithDevTools  from 'redux-devtools-extension';

//initial app state
const initialState = ;

//middleware
const middleware = [thunk];

//...middleware (spread operator) because we want it to be added on to the middleware array
const store = createStore(
    rootReducer, 
    initialState, 
    composeWithDevTools(
        applyMiddleware(...middleware)
        )
    );

export default store;

我还要提一下,当我刷新页面时,调试器会通过一个 componentDidMount 函数,用于解码 jwt 并调用 getUser 的主应用程序。

我相信这就是所有相关代码,但如果需要我可以更新。提前感谢您,对于这个粗制滥造的问题,我们深表歉意。

【问题讨论】:

【参考方案1】:

据我所知,您没有将 getUser 操作发送到商店。

即使在其他操作中,如果您希望处理它们,您仍然需要实际将操作分派到您的 redux 存储。 getUser 本身只是一个动作创建器函数,在这种情况下,它是一个异步动作创建器,它返回一个仍需要分派到商店的函数。

export const loginUser = (credentials) => dispatch => 
  axios.post('api_call', credentials)
    .then(res => 
      const token = res.data.token;
      localStorage.setItem('token', token);
      alert("You have logged in successfully!");
      dispatch(getUser(token)); // <-- dispatch getUser action!
    );

【讨论】:

是的!我应该把我得到的例外作为一个提示。哦,好吧,至少我再也不会犯这个错误了,现在我对 redux 有了更多的了解。谢谢!

以上是关于为啥 redux 只在浏览器刷新时更新?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 React 应用程序只在新选项卡中看起来不错?

如何在 redux 状态更新时自动刷新组件

为啥刷新浏览器时 Application_BeginRequest() 会触发两次?

刷新浏览器时如何使react-router v4:id-path工作?

Next js 应用刷新时,useEffect 不调度 redux saga 动作并更新状态

Redux 路由器 - 刷新后如何重播状态?