nextjs@11.1.2 静态生成模式做预载数据的功能

2021-09-07 02:05:45 +08:00
 ragnaroks

注:本文不考虑 umi 、vite 等情况。

场景:运营后台,必须获取一个有效用户数据结构才能进入,且没有登入功能(登入功能在用户中心),用户数据通过一个接口取得。

基于 vue 的 nuxtjs 框架,直接就有 middleware 这种东西,可以做路由拦截的同时,也可以做数据预载,比如在进入某个页面组件之前,先获取这个组件的数据,完事后直接塞到组件的 props 里面去;缺点就是如果这个接口响应时间太长,就会有明显的“卡屏”感受,一般也是会单独做一个加载的提示组件告诉用户没卡。在使用 nuxtjs 的时候,直接在根组件上获取数据,等待完成后再进入具体的页面组件,体验非常接近传统的服务端渲染,用户打开页面的时候,他需要的一切都已经准备妥当。

在我接触到的范围内,nextjs 已经这么多年了,但没有加上路由守护功能,无法在首次加载时做路由拦截,比如没有获取到有效数据则重定向到用户中心。且 nextjs 不能像 nuxtjs 那样在 App 组件上使用 vuex(recoil),也就不能在定义 atom 的时候获取数据。

经过 3 个小时的测试,我给出这样一个办法:

/* _app.js */

// 此组件内不能使用 recoil 的 hook

import {RecoilRoot} from 'recoil';
import NextWrap from '_wrap';

export default function App({Component,pageProps,router}){
  return <RecoilRoot>
    <NextWrap Component={Component} pageProps={pageProps} router={router} />
  </RecoilRoot>;
};

/* _wrap.js */

import {useRecoilState} from 'recoil';
import sessionAtom from 'store/user/session';
import {useEffect, useState} from 'react';

export default function NextWrap({Component,pageProps,router}){
  const [session,setSession]=useRecoilState(sessionAtom);
  const [hasError,setHasError]=useState(false);

  if(session.id<1 || !session.username){
    fetch(usercenter).then(function(data){
      setSession({id:data.id,username:data.username});
    }).catch(function(exception){
      setHasError(true);
    });
    // error-alert-component 组件上可以显示到用户中心的链接,由用户主动跳转过去
    return hasError ? <error-alert-component /> : <loading-data-component />;
  }

  return <Component {...pageProps} router={router} />;
};

在 App 之内,在 Pages 之外,再提供一个包裹层,把这个包裹层当 "App" 组件用,这样就可以在 "App" 组件上使用 recoil 了,并且在这里请求用户数据写到 recoil 里面去,整个网站都将获得对用户数据的访问能力。

以上代码已经在生产环境跑了一周了,除了部分用户有些不习惯(之前是直接进入登入页,现在需要多点一次)以外没有其它任何问题。

大概是需求太奇葩?我来回翻 nextjs 的 issue 只找到几个与我有类似需求的情况,当然都被无视掉了。单位的钱不好赚啊。

1715 次点击
所在节点   Next.js
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/800274

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX