React-Router-Dom v6中的私有路线不起作用

发布于 2025-02-11 07:28:35 字数 3268 浏览 1 评论 0原文

我正在尝试将preectectedRoute用作 我看不出为什么代码不起作用,我没有遇到任何错误,但是在/account它应该显示< profile/>,并且是空白,我可以看到标题和页脚,但是整个< profile/>缺少 在尝试使用私有之前,我可以在任何问题上显示配置文件

我的preectedRoute.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;

I'm trying to use ProtectedRoute as
I can't see why the code isn't working, I'm not getting any error, but at /account it should display <Profile/> and it's blank, I can see the header and footer, but the whole <Profile/> is missing
before trying to use a PrivateRoute, I could display Profile with any problem.

my 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;

my 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;

and my Profile

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凶凌 2025-02-18 07:28:35

您正在渲染相同的“/account”路径的两个路由。 preectedRoute在其自己的自关路路线上渲染,因此第二个路由渲染配置文件无法实现。

<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>

删除路径>从布局路由呈现preatectedRoute的道具,并确保它是 实际 包装其他路由组件。您还可以在RRDV6中删除此prop时删除所有路线上的精确

示例:

<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>

preectedRoute组件似乎不等待用户状态在渲染受保护内容或重定向的utlet之前要填充。在填充用户状态时,应用一些条件渲染以渲染加载指示器或类似。

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;

You are rendering two routes for the same "/account" path. ProtectedRoute is rendered on its own self-closing route, so the second route rendering Profile is unreachable.

<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>

Remove the path prop from the layout route rendering the ProtectedRoute and ensure it is actually wrapping other Route components. You may as well also remove the exact prop on all the routes as this prop was removed in RRDv6.

Example:

<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>

The ProtectedRoute component doesn't appear to wait for the user state to populate before rendering either the Outlet for protected content or the redirect. Apply some conditional rendering to render a loading indicator or similar while the user state is populated.

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文