刷新<Routes>成功登录和注销后react-router v6中的组件[重复]

问题描述 投票:0回答:1

我在

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
reactjs redirect routes react-router
1个回答
0
投票

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 />);
}
© www.soinside.com 2019 - 2024. All rights reserved.