Protect a SPA application in React with a login - why does this methodology not work?

el *_*00b 5 reactjs react-router-dom

I am learning ReactJS so I am completely new at this.

I created an authentication/authorization service that I know works in React just fine. What I am trying to do is protect the primary application with a login. As I understand, I want a high-order component such as this in order to protect the core of the application:

const withAuth = (Component) => {
  const AuthenticatedComponent = () => {
    const isAuthenticated = MyService.isUserAuthenticated();
    if (!isAuthenticated) {
      return <Navigate to="/login" />;
    }
    return <Component />;
  };

  return AuthenticatedComponent;
};

export default withAuth;
Run Code Online (Sandbox Code Playgroud)

I have two components that are pretty simple to test the theory that are both very similar. Essentially they look like this:

export default function DefaultLandingPage() {
  return(
    <>
    <div>
      This would be the dashboard page after login.
    </div>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)
export default function LoginPage() {
  return(
    <>
    <div>
      This is where the user would log in.
    </div>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

I tried to use these in my App.js file.

First I tried this:

function App() {
  return (
    <>
    <Routes>
      <Route path="/" exact component={withAuth(DefaultLandingPage) } />
      <Route path="/login" element={ <LoginPage /> } />
    </Routes>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

That results in:

Matched leaf route at location "/" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.

I tried changing it to:

<Route path="/" exact element={ withAuth(DefaultLandingPage) } />
Run Code Online (Sandbox Code Playgroud)

Which results in:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.

Can someone point me in the proper direction?

I did find this post and am headed down that route right now; however, I am not sure what my incorrect logic is here.

Can someone explain why my logic doesn't work here?

我担心的是,我还想用细粒度的权限来保护页面,并希望创建一些功能如下的东西:

<Route path="/" exact element={ withAuth(DefaultLandingPage) } />
<Route path="/some-sub-area" element={ withAuth(withPermission(SomeSubArea, 'permission-xyz')) } />
Run Code Online (Sandbox Code Playgroud)

小智 0

对于第一种情况,请确保您的 prop 的component大写符合Component路由器文档。对于第二个问题,您的withAuth函数返回一个函数引用AuthenticatedComponent rather than treating it as a functional component. Opting to return <AuthenticatedComponent/> should send you in the right direction!