下一个JS-在SSR与CSR中处理_app.js上的getInitialProps

问题描述

我正在尝试创建一个处理js和getinitialProps中的初始路由的Next JS应用程序。我发现此方法可以在服务器或客户端上执行。 到目前为止,我的方法是根据检测我是否在服务器中执行检查是否有ctx内部的req属性,来使用2个不同的处理程序。 这可以解决问题,但感觉不正确。有人可以告诉我是否有更清洁的方法。 所有身份验证都在单独的子域中处理,因此,如果没有cookie或身份验证请求由于其他原因失败,我只需要重定向到auth子域。

import "../../styles/globals.css";

function MyApp({ Component,pageProps }) {
  return <Component {...pageProps} />;
}

MyApp.getinitialProps = async (appContext) => {
    let cookie,user;

    let ctx = appContext.ctx;

    //Check if I am in the server.
    if (ctx.req) {
        cookie = ctx.req.headers.cookie
        //Do auth request.

        //Redirect base on user properties
        // handle redirects using res object
        ctx.res.writeHead(302,{ Location: "/crear-cuenta"});
         
    }  else {
        cookie = window.document.cookie;
        //Do auth request.
        //Redirect base on user properties
        //Do redirects using client side methods (useRouter hook,location.replace)???
    }

    //Return pageProps to the page with the authenticted user @R_456_4045@ion.
    return { pageProps: { user: user } };
  
};

export default MyApp;

解决方法

我认为您的代码足够干净。当然,您仍然可以维护它。

我的建议如下:

MyApp.getInitialProps = async (appContext) => {

在这一行中,您可以使用对象解构技术来使上下文简单明了:

MyApp.getInitialProps = async ({ ctx }) => {

那么您将不再需要以下行:let ctx = appContext.ctx;

可以清除的代码中最重要的部分是在if / else条件下两次编写身份验证请求的区域。我建议您像这样实现该部分:

const cookie = ctx.req ? ctx.req.headers.cookie : window.document.cookie;

尽管我会尝试将所有内容保留在服务器端的getInitialProps中,但在这种情况下,我做了一些小的更改以使cookie如下并仅在服务器端进行处理。

const cookie = cookie.parse(ctx.req ? ctx.req.headers.cookie || "" : undefined);

请注意:我正在使用cookie解析器,您也可以自己安装该软件包。 (npm install cookie

如果您需要在客户端对Cookie进行额外检查,我将在componentdidmount中进行检查,或者如果您在useEffect中使用react挂钩。但这不是必需的。

现在您可以实施一次//Do auth request,这将使代码更简洁,当然也可以减少不必要的重复。