我在
React
应用程序中实现路由和导航时面临两个问题,并且我正在使用 react-router-dom
v6 库来实现路由目的。
第一个问题:当我登录时,我应该使用不起作用的编程重定向重定向到
Dashboard page
。因为我的 <Routes>
组件仍在获取用户的旧用户对象,该对象在登录前为 null。 <Routes>
组件应在成功登录后刷新以获取有效的用户对象。
第二个问题:(优先级较低,但仍然)菜单标签
Login
没有更改为Logout
,因为它是单独的组件,我不想使用一些道具来刷新,需要一些智能的方法达到相同的效果,登录应该自动更改为注销,而不必担心道具之类的。
代码结构如下:
App.jsx
function App() {
return (
<div className="main_page_wrapper">
<MainNavigation />
<AppRouter />
</div>
);
}
export default App
MainNavigation.jsx
function MainNavigation() {
const logout = () => {
localstorage.setItem('user', null);
}
return (
<div className="site_nav_lists">
<ul className="main_navigation_list">
<li><NavLink to={'/'} title="Home">Home</NavLink></li>
<li><NavLink to={'/dashboard'} title="Dashboard">Dashboard</NavLink></li>
<li><NavLink to={'/contact'} title="Contact">Contact</NavLink></li>
</ul>
<ul className="user_navigation_list">
{
localstorage.getItem(user) ?
<li><NavLink title="Logout" onClick={logout}>Logout</NavLink></li> :
<li><NavLink to={'/login'} title="Login">Login</NavLink></li>
}
</ul>
</div>
);
}
export default MainNavigation
AppRouter.jsx
const AppRouter = () => {
const loggedInUser = localstorage.getItem('user'); // this should be refreshed on successful login
return (
<Routes>
<Route exact path="/login" element={<Login />} />
<Route element={<ProtectedRoute user={loggedInUser} />}>
<Route path="/dashboard" element={<Dashboard />} />
</Route>
<Route exact path="/contact" element={<Contact />} />
<Route exact path="/" element={<Home />} />
<Route path="*" element={<Page404 />} />
</Routes>
);
}
export default AppRouter;
登录.jsx
import { useNavigate } from "react-router-dom";
function Login() {
let navigate = useNavigate();
const submitLoginForm = (e) => {
e.preventDefault();
if (validEmail == true && validPassword == true) {
let loggedInUser = { id: '1', name: 'John Doe' };
localstorage.setItem('user', loggedInUser);
navigate('/dashboard'); // this is giving 404
}
else {
toast.error('Invalid username or password');
}
}
return (<FormComponent />);
}
export default Login
对
localstorage
的更改不是状态更改,也不会导致重新渲染。您应该重构代码,使 user
成为处于状态的对象。 Context 是一个很好的解决方案,因为它可以轻松地将状态值传递到任何需要它的组件中,而无需将其作为 props
向下传递。
export const UserContext = createContext();
// App
function App() {
const [user, setUser] = useState(null);
return (
<div className="main_page_wrapper">
<UserContext.Provider value={{user, setUser}}>
<MainNavigation />
<AppRouter />
</UserContext.Provider>
</div>
);
}
// AppRouter
const AppRouter = () => {
const { user } = useContext(UserContext)
return (
<Routes>
<Route exact path="/login" element={<Login />} />
<Route element={<ProtectedRoute user={loggedInUser} />}>
<Route path="/dashboard" element={<Dashboard />} />
</Route>
<Route exact path="/contact" element={<Contact />} />
<Route exact path="/" element={<Home />} />
<Route path="*" element={<Page404 />} />
</Routes>
);
}
// Login
function Login() {
let navigate = useNavigate();
const { setUser } = useContext(UserContext);
const submitLoginForm = (e) => {
e.preventDefault();
if (validEmail == true && validPassword == true) {
let user = { id: '1', name: 'John Doe' };
setUser(user)
navigate('/dashboard');
} else {
toast.error('Invalid username or password');
}
}
return (<FormComponent />);
}