V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ragnaroks
V2EX  ›  Next.js

[email protected] 静态生成模式做预载数据的功能

  •  
  •   ragnaroks · 2021-09-07 02:05:45 +08:00 · 1580 次点击
    这是一个创建于 933 天前的主题,其中的信息可能已经有所发展或是发生改变。

    注:本文不考虑 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 只找到几个与我有类似需求的情况,当然都被无视掉了。单位的钱不好赚啊。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2918 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 15:17 · PVG 23:17 · LAX 08:17 · JFK 11:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.