我用next-i18next作为i18n库编写了一个简单的nextjs。我通过将语言环境放在/ pages / mysite / mysubsite / [locale] / section /路径中来使用动态路由。我不使用localeSubpaths,因为我想像上面那样修复路径,而不是将语言环境放在路径的末尾。
主程序是这样的
/ pages / mysite / mysubsite / [locale] /section/index.js
import { useRouter } from 'next/router';
import PropTypes from 'prop-types'
import { i18n, Link, withTranslation } from '../../../../../i18n'
const Index = ({isMobileView, t}) => {
const router = useRouter();
const { locale } = router.query;
if (i18n.language !== locale) {
console.log('switching locale from ' + i18n.language + ' to ' + locale);
i18n.changeLanguage(locale);
}
if (isMobileView) {
return (
<div> {t('mobile')}
{locale}
</div>
)
} else {
return (
<div> {t('desktop')}
{locale}
</div>
)
}
};
Index.getInitialProps = async function (context) {
let isMobileView = (context.req
? context.req.headers['user-agent']
: navigator.userAgent).match(
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
)
//Returning the isMobileView as a prop to the component for further use.
return {
isMobileView: Boolean(isMobileView),
namespacesRequired: ['items'],
}
}
Index.propTypes = {
t: PropTypes.func.isRequired,
}
export default withTranslation('items')(Index);
/ pages / i18n就像这样:-
const NextI18Next = require('next-i18next').default;
module.exports = new NextI18Next({
defaultLanguage: 'en',
otherLanguages: ['tw'],
});
而且我仅将两个项目存储在json items.json中,下面存储了第二个:-
{
"mobile": "手機",
"desktop": "桌面"
}
和下面的结尾:-
{
"mobile": "Mobile",
"desktop": "Desktop"
}
我发现程序首次运行时,结果将是:-
desktopopen
并且从chrome控制台日志中正在打印:-
将语言环境从未定义切换到en
并且服务器控制台日志看起来很类似:-
react-i18next :: i18n.languages未定义或为空未定义将语言环境从undefined切换到en
这意味着我已经使用i18n.changeLanguage(locale)更改了本地,而本地本身是正确的。
但是我很迷茫。为什么UI中的语言环境是打开的,而我可以从控制台日志中打印正确的语言环境?
另一个奇怪的是,我已经打开了chrome的控制台,并且还切换到了响应式移动视图。这意味着在第一次运行中,移动代理检测也不起作用。然后我按shift F5刷新页面。 UI变为:-
mobileen
并且控制台日志不会打印任何内容。
同样,这次移动检测正确时,它将打印密钥而不是json的值。
当我第三次按Shift F5时,一切正常。并显示正确的用户界面:-
Mobileen
在整个调试过程中,我试图关闭所有内容(浏览器和节点进程),并一次又一次地重启以观察行为,尽管有些奇怪的是,有时桌面打开不会发生,而就像mobileen代替。这意味着,无论何时打开Desktopopen,移动检测也无法正常进行。我真的无法缓存行为。
使用的库版本如下:-
"dependencies": {
"next": "^9.1.6",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"@quentin-sommer/react-useragent": "^3.1.0",
"next-i18next": "^3.0.1"
}
也/pages/_app.js如下:-
import React from 'react'
import App from 'next/app'
import { appWithTranslation } from '../i18n'
class MyApp extends App {
render() {
const { Component, pageProps } = this.props
return (
<Component {...pageProps} />
)
}
}
export default appWithTranslation(MyApp)
我怀疑是bcoz,问题与状态管理有关,并且已通过将主程序修改为:-]尝试使用react钩子进行切换。
import React, { useState } from 'react'; import { useRouter } from 'next/router'; import PropTypes from 'prop-types' import { i18n, Link, withTranslation } from '../../../../../i18n' const Index = ({isMobileView, t}) => { const router = useRouter(); const [ locale ] = useState(router.query.locale); if (i18n.language !== locale) { console.log('switching locale from ' + i18n.language + ' to ' + locale); i18n.changeLanguage(locale); } if (isMobileView) { return ( <div> {t('mobile')} {locale} </div> ) } else { return ( <div> {t('desktop')} {locale} </div> ) } }; Index.getInitialProps = async function (context) { let isMobileView = (context.req ? context.req.headers['user-agent'] : navigator.userAgent).match( /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i ) //Returning the isMobileView as a prop to the component for further use. return { isMobileView: Boolean(isMobileView), namespacesRequired: ['items'], } } Index.propTypes = { t: PropTypes.func.isRequired, } export default withTranslation('items')(Index);
但是问题几乎相同。唯一的区别是我无法缓存输出为“ desktopopen”的那一刻。
我的问题可以概括为:-
我用next-i18next作为i18n库编写了一个简单的nextjs。我通过将语言环境放在/ pages / mysite / mysubsite / [locale] / section /路径中来使用动态路由。我不使用...
最后我已经解决了这个问题。问题是我不小心将确定和更改语言环境的逻辑放在页面组件本身上,而不是放在getInitialProps上。