ReactJS项目浏览器刷新后跳转至首页而非当前页问题求助
问题根因
- 你用到的
isAuthenticated登录状态存在Redux store中,Redux的状态默认保存在运行内存里,浏览器刷新后所有内存数据会被清空,此时authentic.isAuthenticated会变成初始的false - 你的
PrivateRoute判断未登录就会重定向到根路径/,这就是刷新就跳回首页的直接原因
解决方案(仅类组件实现,无Hooks)
步骤1:登录成功后将登录状态和用户信息持久化到localStorage
找到你处理登录逻辑的代码,登录接口调用成功后,除了dispatch存到Redux,同时存到localStorage:
// 你的登录成功处理逻辑 const loginSuccess = (userInfo) => { // 新增:把登录状态和用户信息存到localStorage localStorage.setItem('isAuthenticated', 'true') localStorage.setItem('mainUser', JSON.stringify(userInfo)) // 保留你原来的dispatch操作 dispatch({ type: 'LOGIN_SUCCESS', payload: userInfo }) }
登出时同步清除localStorage存储的信息:
// 登出处理逻辑 const logout = () => { localStorage.removeItem('isAuthenticated') localStorage.removeItem('mainUser') dispatch({type: 'LOGOUT'}) }
步骤2:修改auth reducer的初始值,从localStorage读取持久化的状态
找到你的auth reducer文件,修改初始state配置,这样刷新后Redux能直接读取本地存储的登录状态:
// 从localStorage读取状态作为初始值 const initialState = { isAuthenticated: localStorage.getItem('isAuthenticated') === 'true', mainUser: localStorage.getItem('mainUser') ? JSON.parse(localStorage.getItem('mainUser')) : null, // 保留你原来定义的其他auth状态字段 } const authReducer = (state = initialState, action) => { switch(action.type) { // 你原来的reducer逻辑无需修改 case 'LOGIN_SUCCESS': return { ...state, isAuthenticated: true, mainUser: action.payload } case 'LOGOUT': return { ...state, isAuthenticated: false, mainUser: null } default: return state } }
步骤3:补充根路径路由规则(可选推荐)
你当前的App.js没有匹配根路径/的路由,未登录重定向到/会出现空白页,建议补充对应规则:
import React, { Component } from "react"; import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom"; import Homepage from "./homepage/Homepage"; import Contacts from "./contacts/Contacts"; import PrivateRoute from "./private-route/PrivateRoute"; import MoviesDetails from "./MoviesDetails/MoviesDetails"; // 如有登录页可在此导入 // import Login from "./login/Login"; class App extends Component { render() { return ( <Router> <div className="App"> <Switch> <PrivateRoute exact path="/homepage" component={Homepage} /> <PrivateRoute exact path="/contacts" component={Contacts} /> <PrivateRoute exact path="/moviesDetails" component={MoviesDetails} /> {/* 补充根路径匹配逻辑 */} <Route exact path="/" render={() => { const isLogin = localStorage.getItem('isAuthenticated') === 'true' // 已登录跳转首页,未登录跳转登录页 return isLogin ? <Redirect to="/homepage" /> : <Redirect to="/login" /> }} /> {/* 如有登录页可在此配置路由 */} {/* <Route exact path="/login" component={Login} /> */} </Switch> </div> </Router> ); } } export default App;
可选进阶:持久化访问路径,登录后跳回上次访问页面
如果你需要实现用户未登录时访问某页面,登录完成后直接跳转到该页面,可按如下方案实现:
- 修改
PrivateRoute.js,记录用户待访问的路径:
import React from "react"; import { Route, Redirect } from "react-router-dom"; import { connect } from "react-redux"; import PropTypes from "prop-types"; const PrivateRoute = ({component: Component, authentic, ...rest}) => ( <Route {...rest} render={ props => authentic.isAuthenticated === true ? ( <div> <Component {...props} /> </div> ) : ( // 把待访问的路径存到localStorage localStorage.setItem('redirectPath', props.location.pathname), <Redirect to="/login" /> ) } /> ); PrivateRoute.propTypes = { authentic: PropTypes.object.isRequired }; const mapStateToProps = state => ({ authentic: state.auth }); export default connect(mapStateToProps)(PrivateRoute);
- 登录成功后读取存储的路径跳转:
// 登录成功后的跳转逻辑 const afterLogin = () => { const redirectPath = localStorage.getItem('redirectPath') || '/homepage' localStorage.removeItem('redirectPath') this.props.history.push(redirectPath) }
内容的提问来源于stack exchange,提问作者user16622035
相关产品推荐
相关产品推荐

