繁体   English   中英

React-router-dom v6 中的 PrivateRoute 不起作用

[英]PrivateRoute in React-router-dom v6 isnt working

我正在尝试使用 ProtectedRoute,因为我看不出为什么代码不起作用,我没有收到任何错误,但在/account它应该显示<Profile/>并且它是空白的,我可以看到标题和页脚,但在尝试使用PrivateRoute之前缺少整个<Profile/> ,我可以显示Profile有任何问题。

我的 ProtectedRoute.js

 import React from "react";
    import { useSelector } from "react-redux";
    import { Navigate, Outlet } from "react-router-dom";

    const ProtectedRoute = () => {
    const {isAuthenticated} = useSelector((state)=>state.user)
    return isAuthenticated ? <Outlet /> : <Navigate to="/login"/>
    }

    export default ProtectedRoute;

我的 app.js

    function App() {

    const {isAuthenticated, user} = useSelector(state=>state.user)
    React.useEffect(() => {

    WebFont.load({
      google:{
        families: [ "Droid Sans", "Chilanka"],
      },
    });

    store.dispatch(loadUser())
    }, []);
  
    return (
    <Router>
      <Header/>
      {isAuthenticated && <UserOptions user={user} />}
      <Routes>
        <Route exact path="/" element={<Home/>}/>
        <Route exact path="/product/:id" element={<ProductDetails/>}/>
        <Route exact path="/products" element={<Products/>}/>
        <Route path="/products/:keyword" element={<Products/>}/>
        <Route exact path="/search" element={<Search/>}/>
        <Route exact path="/account" element={<ProtectedRoute/>}/>
          <Route exact path="/account" element={<Profile/>}/>
        <Route exact path="/login" element={<LoginSignUp/>}/>
      </Routes>
    <Footer/>
    </Router>
    );
   }

   export default App;

和我的个人资料

const Profile = () => {
 const { user, loading, isAuthenticated} = useSelector((state) => state.user);

 const navigate = useNavigate();

useEffect(() => {
    if(isAuthenticated === false){
        navigate("/login");
    }
}, [navigate,isAuthenticated])
return (
        <Fragment>
          <MetaData title={`${user.name}'s Profile`} />
          <div className="profileContainer">
            <div>
              <h1>My Profile</h1>
              <img src={user.avatar?.url} alt={user.name} />
              <Link to="/me/update">Edit Profile</Link>
            </div>
            <div>
              <div>
                <h4>Full Name</h4>
                <p>{user.name}</p>
              </div>
              <div>
                <h4>Email</h4>
                <p>{user.email}</p>
              </div>
              <div>
                <h4>Joined On</h4>
                <p>{String(user.createdAt).substr(0, 10)}</p>
              </div>                
              <div>
                <Link to="/orders">My Orders</Link>
                <Link to="/password/update">Change Password</Link>
              </div>
            </div>
          </div>
        </Fragment>
  );
};

export default Profile;

您正在为相同的"/account"路径呈现两条路线。 ProtectedRoute是在自己的自闭路由上渲染的,所以第二个路由渲染Profile是不可达的。

<Routes>
  <Route exact path="/" element={<Home/>}/>
  <Route exact path="/product/:id" element={<ProductDetails/>}/>
  <Route exact path="/products" element={<Products/>}/>
  <Route path="/products/:keyword" element={<Products/>}/>
  <Route exact path="/search" element={<Search/>}/>
  <Route exact path="/account" element={<ProtectedRoute/>}/>
  <Route exact path="/account" element={<Profile/>}/> // <-- unreachable, oops!
  <Route exact path="/login" element={<LoginSignUp/>}/>
</Routes>

从呈现ProtectedRoute的布局路由中移除path道具,并确保它实际上包装了其他Route组件。 您也可以删除所有路线上的exact道具,因为该道具已在 RRDv6 中删除。

例子:

<Router>
  <Header/>
  {isAuthenticated && <UserOptions user={user} />}
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/product/:id" element={<ProductDetails />} />
    <Route path="/products" element={<Products />} />
    <Route path="/products/:keyword" element={<Products />} />
    <Route path="/search" element={<Search />} />
    <Route element={<ProtectedRoute />}>
      <Route path="/account" element={<Profile />} /> // <-- wrapped by layout route!
    </Route>
    <Route path="/login" element={<LoginSignUp />} />
  </Routes>
  <Footer/>
</Router>

ProtectedRoute组件在呈现受保护内容的Outlet或重定向之前似乎不会等待user状态填充。 在填充user状态时应用一些条件渲染来渲染加载指示器或类似内容。

import React from "react";
import { useSelector } from "react-redux";
import { Navigate, Outlet } from "react-router-dom";

const ProtectedRoute = () => {
  const user = useSelector((state) => state.user);

  if (!user) return null; // <-- or loading indicator, etc...

  return user.isAuthenticated
    ? <Outlet />
    : <Navigate to="/login" replace />;
}

export default ProtectedRoute;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM