【问题标题】:Component is rendering props.children before parent logic is completed组件在父逻辑完成之前渲染 props.children
【发布时间】:2021-10-01 18:27:13
【问题描述】:

我正在尝试自学 next.js,但我遇到了一些身份验证逻辑问题。

我有一个页面protected/profile,如果用户未登录,我想阻止用户访问该页面。为了检查这一点,我正在通过 getServerSideProps 检索一些用户数据,然后我试图通过将用户数据返回给组件,然后组件将其传递给名为Protected 的子元素。受保护的是执行逻辑来检查用户是否登录,如果用户登录,则应通过返回 props.children 显示个人资料页面。

如果用户没有登录,他们应该被重定向到/

但是,配置文件组件似乎只是呈现配置文件页面,而不是等待受保护的逻辑完成。如果我在注销时尝试访问个人资料页面,我会收到一条错误消息,提示找不到 user.user_metadata,而实际上我应该被重定向。

控制台日志最终是

Profile log
protected.tsx:7 Protected log
protected.tsx:17 Protected: Has user
const Profile = ({user} : {user: User}) => {
    console.log("Profile log");
    return (
        <Protected user={user}>
            <h1>This is Profile</h1>
            <h1>Hello, {user.user_metadata.full_name}!</h1>
            <p> Your email : {user.email}</p>
        </Protected>
    )
}

export const getServerSideProps: GetServerSideProps = async ({req}) => {
    const {user} = await supabaseClient.auth.api.getUserByCookie(req);
    return { props: {user: user}}
}

export default Profile;
export default function Protected(props: {user: User, children}){
    console.log("Protected log");
    if(!props.user){
        console.log("Protected: Null user");
        return {
            redirect: {
                destination: "/",
                permanent: false
            }
        }
    }
    console.log("Protected: Has user");
    return props.children;
}

【问题讨论】:

  • 您是否尝试在注销时记录user 对象?此外,你不能从 React 组件返回对象(redirect 等),即使你的 user 逻辑没问题,这也不起作用。
  • @Danila 重定向工作完全正常,否则这里不是问题
  • 它不可能工作,你返回的是对象而不是 JSX。
  • 您从教程中复制错误。您可以从 getServerSideProps 函数返回 redirect 对象,但不能从 React 组件返回。
  • @Danila 对不起,是的,我忘记了我已经更改了教程中给出的原始代码

标签: reactjs next.js


【解决方案1】:

所以,首先,正如我在评论中所说,你不能从 React 组件返回 redirect 对象,这是行不通的。如果你想使用redirect 对象,你需要从getServerSideProps 返回它。或者使用useRouter 或类似的东西制作一些自定义逻辑。

其次,您应该输入user 作为可选,因为它可能不存在(根据您的代码):

const Profile = ({user} : {user?: User}) => {
    console.log("Profile log");
    return (
        <Protected user={user}>
            <h1>This is Profile</h1>
            <h1>Hello, {user.user_metadata.full_name}!</h1>
            <p> Your email : {user.email}</p>
        </Protected>
    )
}

现在您将看到 Typescript 错误,您正在尝试访问可能未定义的对象的属性。

您可以做的是使用用户逻辑制作单独的组件:

const Profile = ({user} : {user?: User}) => {
    console.log("Profile log");
    return (
        <Protected user={user}>
            <UserProfile user={user} />
        </Protected>
    )
}

或者让Protected接受children as a function

const Profile = ({ user }: { user?: User }) => {
  console.log('Profile log');
  return (
    <Protected user={user}>
      {() => (
        <>
          <h1>This is Profile</h1>
          <h1>Hello, {user.user_metadata.full_name}!</h1>
          <p> Your email : {user.email}</p>
        </>
      )}
    </Protected>
  );
};

Protected 大致如下:

export function Protected(props) {
  if(!props.user){
    // Make some other redirect logic, you current implementation with object won't work
  }
  // Notice here we calling the children
  return props.children();
}

【讨论】:

    猜你喜欢
    • 2018-09-19
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多