reactjs 如何等待会话加载?

6ju8rftf  于 2023-01-04  发布在  React
关注(0)|答案(2)|浏览(142)

我使用next-auth进行用户身份验证,当用户登录时,我将accessToken存储在session
在我的页面[trackId].js中,每次用户更新音轨时,refresh的值(这是一个useState钩子)都会改变,因此useEffect会运行并获得新音轨。

useEffect(() => {
    async function refreshPage() {
      console.log(session); // <-- output in the image below
      await axiosPrivateWithToken(session.data.accessToken)
        .get(`/track/get/${trackId}`)
        .then((res) => {
          setGetedTrack(res.data);
        })
        .catch((error) => {
          console.log("refreshPage for track has catched an error : ", error);
        });
    }
    refreshPage();
  }, [refresh]);

到目前为止一切正常问题是当用户手动输入URL时,我得到这个错误
TypeError:无法读取未定义的属性(阅读“accessToken”)
这是因为当窗口重新加载时,会话是loading并且还没有accessToken,数据仍然是undefined

有什么建议吗?谢谢你的关注

zf9nrax1

zf9nrax11#

您不能直接将session.data.accessToken添加到依赖列表中吗?这样,一旦您获得访问令牌,它就会刷新。

useEffect(() => {
  async function refreshPage() {
    if (!session.data || !session.data.accessToken) return;
    console.log(session); // <-- output in the image below
    await axiosPrivateWithToken(session.data.accessToken)
      .get(`/track/get/${trackId}`)
      .then((res) => {
        setGetedTrack(res.data);
      })
      .catch((error) => {
        console.log("refreshPage for track has catched an error : ", error);
      });
  }
  refreshPage();
}, [refresh, (session.data || { accessToken: '' }).accessToken]);
s1ag04yj

s1ag04yj2#

与其每次需要时都检查是否定义了session,不如这样做,您可以声明一个Auth组件:

function Auth({ children }: { children: JSX.Element }) {
  // if `{ required: true }` is supplied, `status` can only be "loading" or "authenticated"
  const router = useRouter();
  const { status } = useSession({ required: true, onUnauthenticated() {
    router.push('/login');
  }, })

  if (status === "loading") {
    return <div>Loading...</div>
  }

  return children
}

在your _app.tsx中,您可以像这样添加它,这样会话将始终被定义:

<Layout>
      {Component.auth ? (
        <Auth>
          <Component {...pageProps} />
        </Auth>
      ) : (
        <Component {...pageProps} />
      )}
  </Layout>

因此,如果你需要一个页面,其中会话总是被定义,你只需要添加一个Auth属性到你的页面,例如,如果你有一个名为'account'的页面:

Account.auth = {
    
}

然后,会话将始终在页面中定义,否则您将被重定向到/login

相关问题