如何在页面渲染 Next.js 之前获取数据

时间:2021-05-17 14:19:37

标签: javascript reactjs redirect fetch next.js

所以这是我的问题:

我在我的项目中使用 Next.js,我通过 OAuth 服务对用户进行身份验证。因此用户的流程如下:

用户点击“登录按钮”-> 用户被重定向到 OAuth 提供商以确认 -> 正在使用 url 查询参数 https://kupbsv.vercel.app/?code=1a6a0490bbgCdef75b399e30d&state=2d601e4c-9660-40ff-a1c8-de241844b1c0 -> 将用户重定向回我的应用程序 我的应用程序使用此参数获取 Access Tokens 并将其保存在本地存储中 -> 然后我使用这个令牌从提供者获取用户数据并将其显示在 profile 组件

该过程正常工作,但在重定向回我的应用程序后,我仍然看到 LogIn button,就像没有用户一样,但身份验证已完成,我在本地存储中有 Access Token。页面重新加载后一切正常,所以问题是在获取数据之前呈现页面。现在,在使用查询参数重定向以摆脱它们之后,我通过使用 router.push('/home') 的解决方法解决了它。如果没有 router.push() 在页面呈现前获取数据,我能做些什么来解决这个问题。

这是我的代码:

Header.js

export default function Header(props) {
  const { query } = useRouter();
  const router = useRouter();
  const [userName, setUserName] = useRecoilState(recoilUserName)
  const [userPrimaryPaymail, setUserPrimaryPaymail] = useRecoilState(recoilUserPrimaryPaymail)
  const [userEmail, setUserEmail] = useRecoilState(recoilUserEmail)
  const [userAvatarUrl, setUserAvatarUrl] = useRecoilState(recoilUserAvatarUrl)
  const [userStatus, setUserStatus] = useRecoilState(recoilUserStatus)
  const [userAmount, setUserAmount] = useRecoilState(recoilUserAmount)
  const [userCurrency, setUserCurrency] = useRecoilState(recoilUserCurrency)
  const [userId, setUserId] = useRecoilState(recoilUserId)
  const [refreshToggle, setRefreshToggle] = useState(true)


      const userProfile = async() => { 
        if (query.code && !userId) { 
          await handleAuthuser();
          const { profile, balance, userStatus } = await getUserData();
          setUserName(profile.name);
          setUserPrimaryPaymail(profile.primaryPaymail);
          setUserEmail(profile.email);
          setUserAvatarUrl(profile.avatarUrl);
          setUserStatus(userStatus.data.status);
          setUserAmount(balance.amount);
          setUserCurrency(balance.currency);
          setUserId(profile.id);  
        }

        if (storage.getItem('mb_js_client:oauth_access_token') && !userId) {
          const { profile, balance, userStatus } = await getUserData();
          setUserName(profile.name);
          setUserPrimaryPaymail(profile.primaryPaymail);
          setUserEmail(profile.email);
          setUserAvatarUrl(profile.avatarUrl);
          setUserStatus(userStatus.data.status);
          setUserAmount(balance.amount);
          setUserCurrency(balance.currency);
          setUserId(profile.id); 
        } 
      }
      userProfile();


return (
    <div className="main">
      <header className="header">
        <Link as="/" href="/" ><a className="logo">KUPBSV</a></Link>
          <a className="push" >
            {!userId ? <LoginDialog /> :
            <Profile name={userName} userId={userId} primaryPaymail={userPrimaryPaymail} userEmail={userEmail} userAvatar={userAvatarUrl} userAmount={userAmount} userCurrency={userCurrency} userStatus={userStatus}/> }
          </a>
          <a><SimpleMenu userId={userId} /></a>
      </header>
 

getUserData.js

const { MoneyButtonClient } = require('@moneybutton/api-client')

export default async function getUserData () {
    const client = new MoneyButtonClient('xxxxxxxxxxxxxxx');

    const { id } = await client.getIdentity()
    const status = await fetch( 'https://kyc.blockpass.org/kyc/1.0/connect/xxxxxx/refId/'+id, {
        headers: {
            'Authorization': 'xxxxxxxxxxxx'
        },
    });
    const userStatus = await status.json()
    const profile = await client.getUserProfile(id)
    const balance = await client.getBalance(id)
    console.log(userStatus);

    return {
        profile: profile,
        balance: balance,
        userStatus: userStatus
    }

handleAuth.js

const { MoneyButtonClient } = require('@moneybutton/api-client')

export default async function handleAuthuser () {
    const client = new MoneyButtonClient('xxxxxxxx');
    client.handleAuthorizationResponse();
    router.push('/home')

}

所以在使用 LoginDialog 后,用户被重定向到 MoneyButton OAuth 服务,然后他被重定向回我的应用程序,并在 url 中使用查询参数。 handleAuth 函数接受查询参数并获取访问令牌以将其保存在本地存储中。 getUserData 正在使用令牌获取用户数据。

0 个答案:

没有答案