likes
comments
collection
share

Next.js _app.tsx使用getInitialProps

作者站长头像
站长
· 阅读数 244

在使用Next.js开发时我们通常是使用内置的SSR服务,很多网站喜欢在网站DOM挂载后再进行user_info的请求,但是次方法会使得Header的布局偏移,组件的切换很影响用户体验。所以很多时候我们会在_app组件中进行请求并使用服务器渲染。 当然_app目前是不支持getServerSideProps的只能使用getInitialProps 官方说会支持,但是在2020年就说了,2年了还是无法使用。所以我们只能是使用getInitialProps了。

import { NextPage } from "next";
import type { AppProps, AppContext } from "next/app";
interface Props extends AppProps {
  userInfo: UserStateAttributes | null;
}
const APP: NextPage<Props> = ({ Component, pageProps, userInfo }) => {
  return (
    <>
      <RecoilRoot initializeState={({ set }) => set(userDataContext, userInfo)}>
        <SWRConfig value={{ revalidateOnFocus: false }}>
          <Sign />
          <Component {...pageProps} />
        </SWRConfig>
      </RecoilRoot>
    </>
  );
};

//! APP组件无法使用getServerSideProps
//? 因为是APP组件的原因,ctx并不是顶级的对象参数只是一个属性
APP.getInitialProps = async (params): Promise<any> => {
  let { ctx } = params as unknown as AppContext;
  // ? article页面不请求,防止被redis缓存
  if (ctx.pathname.startsWith("/article/") && ctx.pathname != "/article/editor") {
    return { userInfo: null };
  }

  let { token } = cookieParse(ctx?.req?.headers?.cookie + "");
  if (!token) {
    return { userInfo: null };
  }

  return await axios
    .get("/user/info", {
      headers: { authorization: token },
    })
    .then(res => {
      return { userInfo: res.data.data || null };
    })
    .catch(() => ({ userInfo: null }));
};
export default APP;

其实也是非常的简单,但是要注意的是,在_app组件中ctx参数不在是最顶级的蚕食,我们获取ctx的时候要使用一个断言。在获取到想要的信息后传递给组件即可。同时在获取请求的参数时需要注意,否则可能无法获取到正确的请求参数。