簡體   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