如何重构登录重定向的常见反应代码?

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

我正在开发一个 React 应用程序,很多(但不是全部)页面都包含此代码:

export default function MyPage() {
  const { isAuthenticated, loginWithRedirect } = useAuth0<User>();

  const handleSignIn = async () => {
    await auth.login(loginWithRedirect);
  };

  if (!isAuthenticated) {
    return <SignIn onSignIn={handleSignIn} />;
  }

  // ...
}

寻求一些有关如何重构此内容的建议,以便它不会在多个页面上重复。钩子合适吗?或者某种父组件包装器???

reactjs authentication refactoring auth0
1个回答
1
投票

您看过内置的 HOC withAuthenticationRequired 吗?

如果您需要更多自定义,您可以有效地重新创建

withAuthenticationRequired
,但可以更多地自定义它:

组件包装器效果很好:

const RequiresAuthenticatedUser = ({children}) => {
    const { isAuthenticated, isLoading, error, loginWithRedirect } = useAuth0<User>();

    const shouldRequireLogin = !isLoading && !isAuthenticated && !error

    useEffect(() => {
       if(!shouldRequireLogin) return;
       auth.login(loginWithRedirect)
    },[shouldRequireLogin,loginWithRedirect])

    if(error) {
      // something went wrong, return an error message
      return <>Error</>
    }

    if(isLoading) {
      return null; // or a spinner, I think null is appropriate
    }

    if(!isAuthenticated) {
       auth.login(loginWithRedirect)
       return nulll;
    }

    return <>{children}</>
}

可以这样使用:

function MyPage() {
  ...
}

export default () => <RequiresAuthenticatedUser><MyPage/></RequiresAuthenticatedUser/>

您可以使用上面的内容创建一个漂亮的小 HOC 来包装您的组件:

const requiresAuthenticatedUser = (Cmp) => (props) => <RequiresAuthenticatedUser><Cmp {...props}/></RequiredAuthenticatedUser>

function MyPage() {
 ...
}

export default requiresAuthenticatedUser(MyPage)

我强烈提倡使用包装组件(或 HOC)而不是挂钩的一个原因是,它将“我是否有用户”的逻辑问题移到了需要用户的组件之外。否则,“我不确定我是否有用户”的逻辑污染组件是非常常见的,而这些组件实际上只应该关心渲染他们知道自己拥有的用户。

© www.soinside.com 2019 - 2024. All rights reserved.