带有静态 NextJS 的 Cookie 导出 return 到页面刷新时的初始值
Cookie with static NextJS export return to initial value on page refresh
我正在构建一个网站,它有两种语言,所以我将所选语言保留在 cookie 上,并在 _app 文件的 getInitialProps 中检索它,然后将其作为上下文 API 值传递。
我通过 useEffect 使 cookie 与语言状态保持同步。
_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 };
};
在开发模式下并正在部署中,它与每次页面刷新完美配合。但是,当我将其导出为静态并将其部署在 Netlify 上时,每次将语言 returns 刷新为其初始值 ("ar").
有没有更好的实现方式,如果没有,上面的实现有什么问题?
经过一些研究,我发现当使用 getInitialProps 或 getStaticProps 静态导出 NextJS 的项目时,NextJS 将创建具有初始值的静态 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>
所以我知道了一些解决这个问题的方法,即
将 NextJS 上传为 SSR,而不是 SSG。
每种语言的重复页面,例如“/en”、“/ar”。
将初始值保存在localStorage中,使用Effect改变它,但需要在渲染组件时处理加载状态并读取localStorage。
使用第三方包。
因此,我采用的方法是为每种语言创建两个页面。
所以文件夹结构变成了这样的东西。
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;
如果我做错了什么,或者您有更好的建议,请在这里评论?
我正在构建一个网站,它有两种语言,所以我将所选语言保留在 cookie 上,并在 _app 文件的 getInitialProps 中检索它,然后将其作为上下文 API 值传递。 我通过 useEffect 使 cookie 与语言状态保持同步。 _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 };
};
在开发模式下并正在部署中,它与每次页面刷新完美配合。但是,当我将其导出为静态并将其部署在 Netlify 上时,每次将语言 returns 刷新为其初始值 ("ar").
有没有更好的实现方式,如果没有,上面的实现有什么问题?
经过一些研究,我发现当使用 getInitialProps 或 getStaticProps 静态导出 NextJS 的项目时,NextJS 将创建具有初始值的静态 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>
所以我知道了一些解决这个问题的方法,即
将 NextJS 上传为 SSR,而不是 SSG。
每种语言的重复页面,例如“/en”、“/ar”。
将初始值保存在localStorage中,使用Effect改变它,但需要在渲染组件时处理加载状态并读取localStorage。
使用第三方包。
因此,我采用的方法是为每种语言创建两个页面。
所以文件夹结构变成了这样的东西。
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;
如果我做错了什么,或者您有更好的建议,请在这里评论?