React-router-dom Link点击无响应及登录后Token丢失问题求助
问题解决方案
一、Link点击无反应,刷新才显示的问题
你的App组件没有被BrowserRouter(或其他Router组件)包裹,react-router-dom的路由相关组件(Link、Switch、Route)必须在Router上下文环境中才能正常工作。
修复步骤:
- 导入
BrowserRouter:import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom'; - 用
Router包裹整个App的返回内容:return ( <Router> <div className="App"> {/* 原有的header、Switch等内容 */} </div> </Router> );
二、页面刷新后Token与用户信息丢失的问题
当前组件初始化时,state的初始值为null,没有从localStorage读取之前保存的数据,导致刷新后state被重置。
修复步骤:
- 使用
useEffect在组件挂载时从localStorage恢复数据:React.useEffect(() => { const savedToken = localStorage.getItem('token'); const savedUser = localStorage.getItem('user'); if (savedToken && savedUser) { setToken(savedToken); setUser(savedUser); } }, []); - 修正signup函数的存储错误:当前代码将整个user对象存入localStorage,应该存
user.username,否则读取时会得到字符串化的对象:// 原代码 localStorage.setItem('user', user); // 改为 localStorage.setItem('user', user.username);
三、登录成功后页面未跳转的问题
登录函数login只更新了state和localStorage,但没有触发页面跳转,需要在登录成功后手动执行跳转逻辑。
修复步骤:
在Login组件中使用useHistory钩子实现跳转:
import { useHistory } from 'react-router-dom'; function Login(props) { const history = useHistory(); const handleLogin = async (userData) => { await props.login(userData); // 登录成功后跳转至事件页 history.push('/events'); }; // 组件其余内容 }
四、Logout的Link缺少跳转目标
当前Logout的Link没有to属性,点击后只会执行logout函数但不会跳转页面,添加跳转目标:
<Link className="nav-link text-light" onClick={logout} to="/login">Logout ({user})</Link>
修正后的完整App.js代码
import React from 'react'; import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom'; import EventsList from './EventsList'; import Login from './Login'; import Signup from './Signup'; import EventDataService from './EventDataService'; function App() { const [user, setUser] = React.useState(null); const [token, setToken] = React.useState(null); const [error, setError] = React.useState(''); // 组件挂载时从localStorage恢复用户数据 React.useEffect(() => { const savedToken = localStorage.getItem('token'); const savedUser = localStorage.getItem('user'); if (savedToken && savedUser) { setToken(savedToken); setUser(savedUser); } }, []); async function login(user = null) { EventDataService.login(user) .then(response => { setToken(response.data.token); setUser(user.username); localStorage.setItem('token', response.data.token); localStorage.setItem('user', user.username); setError(''); }) .catch(e => { setError(e.toString()); }); } async function logout() { setToken(''); setUser(''); localStorage.setItem('token', ''); localStorage.setItem('user', ''); } async function signup(user = null) { EventDataService.signup(user) .then(response => { setToken(response.data.token); setUser(user.username); localStorage.setItem('token', response.data.token); localStorage.setItem('user', user.username); setError(''); }) .catch(e => { console.log(e); setError(e.toString()); }); } return ( <Router> <div className="App"> <header className="App-header"> <ul className="nav justify-content-center"> { user ? ( <li className="nav-item"> <Link className="nav-link text-light" onClick={logout} to="/login">Logout ({user})</Link> </li> ) : ( <> <li className="nav-item"> <Link className="nav-link text-light active" aria-current="page" to="/login">Login</Link> </li> <li className="nav-item"> <Link className="nav-link text-light" to="/signup">Sign Up</Link> </li> </> ) } </ul> <h1 className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Welcome {user ? user : ''}! </h1> </header> <div className='container'> <Switch> <Route exact path={["/", "/events"]} render={(props) => <EventsList {...props} token={token} /> }> </Route> <Route path="/login" render={(props) => <Login {...props} login={login} /> }> </Route> <Route path="/signup" render={(props) => <Signup {...props} signup={signup} /> }> </Route> </Switch> </div> </div> </Router> ); } export default App;
内容的提问来源于stack exchange,提问作者ilsurealism
相关产品推荐
相关产品推荐

