React Router 4 结合Redux存储认证状态时受保护路由失效问题
问题分析与解决方案
你的问题根源在于authed初始值是空对象{},而JavaScript中空对象属于真值,所以!!authed的结果永远是true——这就导致你的PrivateRoute不管用户是否真的完成认证,都会直接渲染受保护组件,不会触发跳转到登录页的逻辑。
下面是具体的修复方案:
方案1:修正authed的初始值与判断逻辑
第一步:调整Reducer的初始状态
把authed的初始值从空对象改成false或null(代表未认证状态):
// 你的认证Reducer示例 const authReducer = (state = { authed: false }, action) => { switch (action.type) { case 'LOGIN_SUCCESS': return { ...state, authed: true }; // 登录成功设为true case 'LOGOUT': return { ...state, authed: false }; // 登出设为false default: return state; } };
第二步:简化PrivateRoute的判断逻辑
因为authed现在是布尔值,直接判断即可,不需要!!转换:
import { Route, Redirect } from 'react-router-dom'; import { connect } from 'react-redux'; function PrivateRoute({ component: Component, authed, ...rest }) { return ( <Route {...rest} render={(props) => authed ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: '/login', state: { from: props.location } }} /> ) } /> ); } // 将Redux状态映射到组件props const mapStateToProps = (state) => ({ authed: state.auth.authed, // 根据你的store结构调整路径,比如state.authed }); export default connect(mapStateToProps)(PrivateRoute);
方案2:如果authed需要存储用户对象(而非布尔值)
如果你的authed字段需要存储用户信息(比如{id: 1, username: 'james'}),那要调整判断逻辑,检查对象是否包含有效用户数据:
第一步:调整Reducer初始状态
const authReducer = (state = { authed: null }, action) => { switch (action.type) { case 'LOGIN_SUCCESS': return { ...state, authed: action.payload.user }; // 登录后存入用户对象 case 'LOGOUT': return { ...state, authed: null }; // 登出后设为null default: return state; } };
第二步:修改PrivateRoute的判断逻辑
检查authed是否存在且包含有效字段(比如id或username):
function PrivateRoute({ component: Component, authed, ...rest }) { return ( <Route {...rest} render={(props) => // 判断用户对象是否有效 authed && authed.id ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: '/login', state: { from: props.location } }} /> ) } /> ); }
额外注意点
- 确保你的PrivateRoute组件已经通过
connect连接到Redux Store,否则authed属性不会被正确传入组件。 - 确认Redux的状态更新是正确的:登录/登出动作触发后,authed的值要正确切换。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

