因此,情况如下。
我正试图得到一个";语言;cookie,以相应地更改UI。例如,如果语言是";阿拉伯语";(ar(,我将布局恢复为";RTL";,反之亦然。
有两种方法可以实现这一点,第一种解决方案是将饼干放入"饼干"中;useEffect((";,像这样。。。
import { parseCookies } from "nookies";
import { useEffect, useLayoutEffect, useState } from "react";
import { StyleSheetManager, ThemeProvider } from "styled-components";
import rtlPlugin from "stylis-plugin-rtl";
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
const [appLanguage, setAppLanguage] = useState("en");
useEffect(() => {
const cookies = parseCookies();
setAppLanguage(cookies.language);
}, []);
useEffect(() => {
history.scrollRestoration = "manual";
if (appLanguage === "ar") {
document.documentElement.classList.add("rtl");
document.documentElement.dir = "rtl";
} else {
document.documentElement.classList.remove("rtl");
document.documentElement.dir = "ltr";
}
}, [appLanguage]);
console.log("Appp Language", appLanguage);
return (
<>
<ThemeProvider theme={theme}>
<StyleSheetManager stylisPlugins={[rtlPlugin]}>
<>
<GlobalStyle />
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
</>
</StyleSheetManager>
</ThemeProvider>
</>
);
}
export default wrapper.withRedux(MyApp);
这是有效的,但你可以想象的问题是,页面会闪烁一小段时间,默认为";英语";直到执行CCD_ 1。
避免这种闪烁行为的另一种方法当然是在_app.tsx级别上使用getInitialProps
,就像这样。。。
MyApp.getInitialProps = async (appContext: AppContext) => {
const cookies = nookies.get(appContext)
const appLanguage = cookies.language;
const appProps = await App.getInitialProps(appContext);
return { appLanguage, ...appProps };
};
现在你有了";appLanguage";在根_app级别上可以使用的道具,用它做任何你想做的事情。
这种方法的唯一问题是;Next.js"团队使用";getInitialProps"在_app级别上,因为根据文档。。。
"这禁用了执行自动静态优化的能力,导致应用程序中的每个页面都在服务器端呈现">
另一方面,你似乎不能使用"getServerSideProps";在root_app级别上。
所以,我的问题是,如何两全其美?从根"获取状态以共享它"_应用程序";级别,而不使用getInitialProps来不在服务器端呈现每个页面?
这可能吗?或者有没有一种方法可以使用";getServerSideProps";在根"中_应用程序";文件
感谢您的帮助。
我不确定这是否有帮助,但可能有一种方法可以避免闪烁。Next.js没有默认为English/LTR,而是具有可配置的i18n路由,它试图使用浏览器标头检测用户的首选区域设置。甚至还有cookie支持,但它必须是硬编码的NEXT_LOCALE
cookie。
即使你已经探索过这个解决方案,我也会把它留给其他有类似问题的人。
===============使用NEXT的解决方案。JS i18n路由======
多亏了@Summer的建议,我能够使用Next.js内置的i18n路由解决方案来解决我的问题,但我并不知道它的存在。
导致UI闪烁的问题是因为我一直在等待useEffect()
函数在_app.tsx中执行,以便在标记中添加某种特殊的CSS类或HTML属性,以便能够在CSS文件中针对该CSS类并切换方向或进行任何其他CSS修改。
但现在,通过使用内置的Next.js i18n路由,Next.jss可以通过查找";NEXT_ LOCALE";cookie,或者如果他找不到他将默认为您选择的默认语言,那么Next.js将添加一个";郎;属性自动添加到直接来自服务器的标签,然后您可以在CSS中针对它切换布局方向。。。
html {
&[lang="ar"] {
direction: rtl;
}
}
这不会导致任何布局闪烁。
再次感谢@Summer的帮助。
下面是一篇关于使用Next.js i18n路由的好文章。https://blog.logrocket.com/complete-guide-internationalization-nextjs/
第页。S: 我决定编辑这个答案,以表扬@Summer。
当前不支持在_app.tsx
上使用getServerSideProps()
。
您可以关注Github上的讨论:https://github.com/vercel/next.js/discussions/10874