Redux派发action后被重置,影院应用登录跳转失败问题排查
问题根因定位
你遇到的问题核心是两个错误共同导致的:
1. AuthReducer 逻辑错误(核心原因)
你当前的AuthReducer的default分支错误返回了初始状态initialState,而不是当前的state。
按照Redux的运行规则:所有dispatch的action会流入所有注册的reducer,每个reducer自行判断是否处理该action。当你Home页面的useEffect触发fetchUpcomingMoviesAction时,这个action没有被AuthReducer的任意case匹配,会直接命中default分支,把整个auth状态重置为初始值,isLoggedIn变回false,触发ProtectedRoute的跳转逻辑回到登录页,这也是你注释掉useEffect后功能恢复的原因——没有额外action触发AuthReducer的default分支,登录状态不会被重置。
2. ProtectedRoute 写法不规范
你当前把登录状态判断放在了Route组件外部,不符合react-router的API规范,会导致路由匹配逻辑异常,也会加剧跳转失败的问题。
额外说明
你在电影相关reducer中能拿到Auth相关的payload属于Redux的正常机制,不是bug:所有action都会传递给所有reducer,所以Auth相关的action自然也会流入电影reducer,打印出来是正常现象。
修复方案
第一步:修复AuthReducer的default分支
将AuthReducer的default分支返回值从initialState改为当前的state:
const authReducer = (state = initialState, action) => { const { type, payload } = action; console.log(payload) switch (type) { case actionTypes.LOGIN_USER: { return { ...state, loading: true, }; } case actionTypes.LOGIN_USER_SUCCESS: { return { ...state, userName: payload.userName, token: `${payload.password}${payload.userName}`, isLoggedIn: true, loading: false, }; } case actionTypes.LOGIN_USER_FAIL: { return { ...state, loading: false, }; } case actionTypes.LOGOUT_USER: { return { ...state, userName: null, token: null, isLoggedIn: false, loading: false, }; } default: // 这里返回当前state,不是initialState return state; } };
第二步:修正ProtectedRoute的写法
把登录判断逻辑放到Route的render回调内,符合react-router的使用规范:
import React from 'react'; import { useSelector } from 'react-redux'; import { Route, Redirect } from 'react-router'; const ProtectedRoute = ({ component: Component, layout: Layout, ...rest }) => { const isLoggedIn = useSelector((state) => state.auth.isLoggedIn); return ( <Route {...rest} render={(props) => isLoggedIn ? ( <Layout> <Component {...props} /> </Layout> ) : ( <Redirect to={{ pathname: '/login', }} /> ) } /> ); }; export default ProtectedRoute;
内容的提问来源于stack exchange,提问作者Ahmed Eid
相关产品推荐
相关产品推荐

