为啥 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 只在浏览器刷新时更新?的主要内容,如果未能解决你的问题,请参考以下文章
为啥刷新浏览器时 Application_BeginRequest() 会触发两次?
刷新浏览器时如何使react-router v4:id-path工作?