1

一句话总结

当我在await serverSideTranslations里面getStaticProps时,loading来自的价值useSession()仍然停留在true.

语境

我使用next-auth.js(v3) 进行身份验证。我已经(感激地)使用了一年没有问题。

const [session, loading]=useSession()是检查某人是否登录的钩子。

loading选项表示会话状态正在更新;它是true在获取会话数据并false完成检查时。 https://stackoverflow.com/a/63191786/870121

我正在添加next-i18next到我的项目中。大部分都在工作,但我遇到了一些困难。

按照.next-i18next

它适用于具有以下功能的页面getServerSideProps:页面加载,next-authuseSession()仍然有效,并且翻译工作没有警告或错误(示例)。例如,像这样/login使用getServerSideProps

export const getServerSideProps = async (context) => {
  const { locale } = context;
  console.log("Have locale, ", locale);
  return {
    props: {
      csrfToken: await csrfToken(context),
      ...(await serverSideTranslations(locale, ["common", "login"])),
    },
  };
};

并且适用于/de/login/en/login 或仅适用于 /login 您可能会在这两个页面上的导航栏(桌面上)的左上角短暂地看到“正在加载......”这个词。这出现在loading是真的,但很快就消失了。 间谍

问题

当我使用它时遇到了一些困难getStaticProps具体来说,loadinguseSession()res . 返回true

案例 A:当我在页面级别使用此代码时,翻译工作,但“加载”值 useSession() 仍然为真

export const getStaticProps = async ({ locale }) => {
  const mood = "determined";
  return {
    props: {
      mood,
      ...(await serverSideTranslations(locale, ["common", "test-page"])),
    },
  };
};

注意awaitbefore serverSideTranslationsthere 的使用;这是故意的,正如我见过的所有文档中所建议的那样。

以上导致该行无法按预期工作;loading停留在true...因此我不知道用户是否已登录。

import { useSession } from "next-auth/client";

const MyComponent = ()=>{
  const [session, loading] = useSession();
  return <div>loading is {loading ? "true" : "false"}</div>
}

关于 的某些东西await serverSideTranslations导致useSession()总是返回[undefined, true]

注意:我使用的是 next-auth v3,而不是 v4。

案例B:我可以删除await之前的关键字serverSideTranslations,然后useSession()正常工作……但是翻译不起作用。

有小费吗?

到目前为止我已经尝试过:

我一直专注于尝试适应next-i18next不需要的await关键字。这让我陷入了连续警告/错误的困境,每个都是由先前的修复引起的:

  • serverSideTranslations在in之前删除“await” getStaticProps
  • 尝试按照https://stackoverflow.com/a/69311205/870121添加react: { useSuspense: false }到 next-i18next.config.js (没有帮助)。
  • 得到错误react-i18next:: You will need to pass in an i18next instance by using initReactI18next。→ 尝试通过添加use: [initReactI18next],来修复next-i18next.config.js
  • 得到错误,“appWithTranslation 调用没有配置”→通过添加到修复_app.js
       import nextI18NextConfig from "../../next-i18next.config.js";
    
       // in page-level components:
       ...(await serverSideTranslations(
         locale,
         ["common", "login"],
         nextI18NextConfig
       )),
    
       // in pages/_app.js
       export default appWithTranslation(AwesoundApp, nextI18NextConfig);
    
    
  • 获取诸如“错误:._nextI18Next.userConfig.use[0].initgetStaticProps;返回的错误序列化”之类的错误 → 添加serializeConfig=false到 next-i18next.config.js 并appWithTranslation按照“不可序列化配置”说明将配置传递给。
    但是,没有一个next-i18next文档建议删除该await关键字,因此这感觉像是一场失败的战斗/可能会带来一些意想不到的后果

我想要帮助的:

我可以在通话中留下await之前的关键字,但仍然没有坚持吗?我可以按照这些文档的建议保留我的使用,但是以某种方式修改我的钩子,这样就不会坚持下去吗?我只是在代码中的其他地方遗漏了一些关键字吗?serverSideTranslationsgetStaticPropsloadingtruenext-i18nextnextauthloadingawait

示例代码

比较这两个页面:

明确一点:我们想loading迅速成为false.

这两个页面具有以下代码。

next.config.js(提炼):

const webpack = require("webpack");
const { i18n } = require("./next-i18next.config");

const moduleExports = {
  i18n, // see require import above
  webpack: (config, options) => {
    config.resolve.fallback = {
      perf_hooks: false, // as per "Quick Solution" on https://dev.to/marcinwosinek/how-to-add-resolve-fallback-to-webpack-5-in-nextjs-10-i6j
      fs: false, // 2022-02-02 hack to fix i18n errors, per https://github.com/isaachinman/next-i18next/issues/935#issuecomment-970024608
      path: false, // 2022-02-02 hack to fix i18n errors, per https://github.com/isaachinman/next-i18next/issues/935#issuecomment-970024608
    };
    return config;
  },
  …
}

next-i18next.config.js(全部):

const path = require("path");

module.exports = {
  i18n: {
    defaultLocale: "en",
    locales: ["en", "de"],
    localePath: path.resolve("./public/locales"),
  },
  // react: { useSuspense: false },
  // useSuspense false does NOT prevent the warning,
  // "react-i18next:: You will need to pass in an i18next instance by using initReactI18next"  on pages that use getStaticProps and serverSideTranslations
  // per https://stackoverflow.com/a/69311205/870121
  // We only get this initReactI18next error when we do NOT use await before serverSideTranslations.
  debug: true,
};

pages/with-await.jsx(全部):
https://awesound-web-iow8f7d1o-awesound.vercel.app/de/test/with-await

// Similar to https://github.com/isaachinman/next-i18next/blob/ee5965183436d9b13d85c9187b3e09983b34ce7f/examples/simple/pages/second-page.js
// This has getStaticProps but not getStaticPaths
// Using 'await' with serverSideTranslations breaks next-auth useSession()

import Layout from "../../components/layout";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import TranslationTestContent from "../../components/test/translationTest";

const usesAwait = true;

const TestPage = ({ mood }) => {
  return (
    <Layout>
      <TranslationTestContent mood={mood} usesAwait={usesAwait} />
    </Layout>
  );
};

export const getStaticProps = async ({ locale }) => {
  const mood = "determined";
  return {
    props: {
      mood,
      ...(await serverSideTranslations(locale, ["common", "test-page"])),
    },
  };
};

export default TestPage;

pages/no-await.jsx(全部):
请参阅https://awesound-web-iow8f7d1o-awesound.vercel.app/de/test/no-await
注意它与pages/with-await.jsx但 usesAwait 是错误的

// Similar to https://github.com/isaachinman/next-i18next/blob/ee5965183436d9b13d85c9187b3e09983b34ce7f/examples/simple/pages/second-page.js
// This has getStaticProps but not getStaticPaths
// Using 'await' with serverSideTranslations breaks next-auth useSession()

import Layout from "../../components/layout";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import TranslationTestContent from "../../components/test/translationTest";

const usesAwait = false;

const TestPage = ({ mood }) => {
  return (
    <Layout>
      <TranslationTestContent mood={mood} usesAwait={usesAwait} />
    </Layout>
  );
};

export const getStaticProps = async ({ params, locale }) => {
  const mood = "determined";
  return {
    props: {
      mood,
      ...serverSideTranslations(locale, ["common", "test-page"]),
    },
  };
};

export default TestPage;

共享组件,

import { useTranslation } from "next-i18next";
import Link from "next/link";
import { useSession } from "next-auth/client";
import { useRouter } from "next/router";
import ExclamationTriangleIcon from "../icons/exclamationTriangle";
import CheckCircleIcon from "../icons/checkCircle";

const TranslationTestContent = ({ mood, usesAwait = true }) => {
  const [session, loading] = useSession({ required: true });
  const { locale } = useRouter();
  const { t } = useTranslation("test-page");

  return (
    <main className="p-12">
      <div className="">Test static page with getStaticProps</div>
      <div className="">Do a full page refresh if you make any changes.</div>
      <h1>This page uses await: {usesAwait ? "yes" : "no"}</h1>
      <div>
        {usesAwait ? (
          <>
            Result: translations work, but the `loading` stays true; we don't
            know if user is logged in.
          </>
        ) : (
          <>
            Result: translations don't work, but the `loading` does become
            false.
          </>
        )}
      </div>
      <h3>Test translation</h3>
      <div className="p-4 bg-seco-200 m-4 flex space-x-6">
        <div>locale: {locale}</div>
        <div>language: {t("language")}</div>
        <div>
          {t("language") === "language" ? (
            <ExclamationTriangleIcon />
          ) : (
            <CheckCircleIcon />
          )}
        </div>
      </div>
      <Link href="/">
        <button type="button" className="btn btn-prim">
          {t("Test page button")}
        </button>
      </Link>
      <h3 className="mt-12">
        Test <pre className="inline">`loading`</pre>
      </h3>
      <div className="p-4 bg-seco-200 m-4">
        <div className="flex space-x-2 items-center">
          <pre className="inline">loading</pre>:{" "}
          <span className="inline">{loading ? "true" : "false"}</span>
          {loading ? <ExclamationTriangleIcon /> : <CheckCircleIcon />}
        </div>
        <div>
          <pre className="inline">session</pre> exists?{" "}
          <span className="inline">{session ? "true" : "false"}</span>
        </div>
      </div>
      <div className="border p-2 overflow-x-scroll">
        session: {JSON.stringify(session)}
      </div>
      <h3>Look at other props</h3>
      <div className="flex space-x-1 gap-x-1">
        Via <pre>props</pre>, we have <pre>mood</pre> = <pre>[{mood}]</pre>.
      </div>
    </main>
  );
};

export default TranslationTestContent;

4

0 回答 0