繁体   English   中英

Cookie with static NextJS 导出页面刷新返回初始值

[英]Cookie with static NextJS export return to initial value on page refresh

我正在构建一个有两种语言的网站,因此我将所选语言保存在 cookie 上并在 _app 文件的 getInitialProps 中检索它,然后将其作为上下文 API 值传递。 我通过 useEffect 将 cookie 与语言 state 保持同步。 _app.js 文件看起来像这样。

import React, { useState, useEffect } from 'react';
import nextCookie from 'next-cookies';
import * as Cookie from 'js-cookie';
import Head from 'next/head';
import { ThemeProvider } from 'emotion-theming';

import Layout from '../components/Common/Layout';
import GlobalStyle from '../components/GlobalStyle';
import { languageState, languageDispatch } from '../hooks/useLanguage';

function MyApp({ Component, pageProps, initialLanguage = 'ar' }) { 
    const [language, setLanguage] = useState(initialLanguage); 
    const changeLanuage = () => {
      setLanguage((prev) => (prev == 'en' ? 'ar' : 'en'));
    };

    useEffect(() => { 
      Cookie.set('language', language); 
    }, [language]);

    return (
    <languageDispatch.Provider value={changeLanuage}>
      <languageState.Provider value={language}>
        <ThemeProvider theme={theme}>
          <Layout>
            <Head>
              <link rel="shortcut icon" href="/svg/favicon.ico" />
            </Head>
            <Component {...pageProps} />
            <GlobalStyle rtl={rtl} />
          </Layout>
        </ThemeProvider>
      </languageState.Provider>
    </languageDispatch.Provider>
  );
} 
MyApp.getInitialProps = async ({ ctx }) => {
    const { language } = cookies(ctx); 
    return { initialLanguage: language }; 
};

在开发模式下并立即部署,它与每次页面刷新都完美配合。 但是,当我将其导出为 static 并将其部署在 Netlify 上时,每次刷新语言都会返回其初始值(“ar”)。

有没有更好的方法来实现它,如果没有,上面的实现有什么问题?

经过一些研究,我发现当使用 getInitialProps 或 getStaticProps 静态导出 NextJS 的项目时,NextJS 将创建 static HTML 具有初始值的页面 - 在这种情况下,“ar” - 所以每当你刷新页面时,内容就会到达使用它的初始值,所以在我之前的方法中,我只是在运行时更改 cookie。 但是,在构建时,它是初始值“ar”。

这是 out/index.html 的代码片段

<script id="__NEXT_DATA__" type="application/json">
  {
    "props": { "initialLanguage": "ar" },
    "page": "/",
    "query": {},
    "buildId": "RmU4iA8jACDFdZr30Xqjo",
    "nextExport": true,
    "isFallback": false
  }
</script>

所以我知道一些解决这个问题的方法,即

  1. 将 NextJS 上传为 SSR,而不是 SSG。

  2. 每种语言的重复页面,例如“/en”、“/ar”。

  3. 将初始值保存在 localStorage 并使用 useEffect 更改它,但是您需要在渲染组件并读取 localStorage 时处理加载 state。

  4. 使用第三方 package。

因此,我采用的方法是为每种语言创建两个页面。

所以文件夹结构变得像这样。

pages
 --[lang]
   --index.js
   --other.js
--index.js

这是 pages/index.js

import Home from '../components/Home';
import Head from '../components/Common/Head';
import { useRouter } from 'next/router';
import getInitialLocale from '../locale/getInitialLocale';
import Spinner from '../components/Common/Spinner/Spinner';

const Index = () => {
  const router = useRouter();
  React.useEffect(() => {
    const href = `/${getInitialLocale()}`;
    router.push({ pathname: href });
  }, []);

  return (
    <div>
      <Head title="Home" />
      <h1 style={{ fontSize: '3rem' }}>Welcome to Here</h1>
    </div>
  );
};

export default Index;

如果我做错了什么,或者你有更好的建议,请在这里评论,好吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM