Reactjs initialprops在第一次运行时不起作用,动态路由在ui中也很奇怪,但在控制台日志中是正确的
我用next-i18next作为i18n库编写了一个简单的nextjs。我使用了动态路由,将区域设置作为/pages/mysite/mysubsite/[locale]/section/放在路径中。我不使用localesubpath,因为我希望像上面那样修复路径,而不是将locale放在路径的末尾 主程序是这样的 /pages/mysite/mysubsite/[locale]/section/index.jsReactjs initialprops在第一次运行时不起作用,动态路由在ui中也很奇怪,但在控制台日志中是正确的,reactjs,next.js,i18next,Reactjs,Next.js,I18next,我用next-i18next作为i18n库编写了一个简单的nextjs。我使用了动态路由,将区域设置作为/pages/mysite/mysubsite/[locale]/section/放在路径中。我不使用localesubpath,因为我希望像上面那样修复路径,而不是将locale放在路径的末尾 主程序是这样的 /pages/mysite/mysubsite/[locale]/section/index.js import { useRouter } from 'next/router'; i
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);
我只存储了json items.json两个键,tw键如下:-
{
"mobile": "手機",
"desktop": "桌面"
}
{
"mobile": "Mobile",
"desktop": "Desktop"
}
最后一段如下:-
{
"mobile": "手機",
"desktop": "桌面"
}
{
"mobile": "Mobile",
"desktop": "Desktop"
}
我发现当程序第一次运行时,结果如下:-
桌面笔
在chrome控制台上,它正在打印:-
将区域设置从未定义切换到en
服务器控制台日志看起来很相似:-
react-i18next::i18n.语言未定义或为空未定义
将区域设置从未定义切换到en
这意味着我已经使用i18n.changeLanguage(locale)更改了本地语言,并且该语言环境本身是正确的
但是我迷路了。为什么UI中的区域设置是打开的,而我可以从控制台日志打印正确的区域设置
另一件奇怪的事是,我打开了chrome的控制台,也切换到了快速响应的移动视图。这意味着移动代理检测在第一次运行时也不起作用。然后我按shift F5刷新页面。用户界面变成:-
美孚林
控制台日志不会打印任何内容
同样,它打印的是密钥而不是json的值,而这次移动检测是正确的
当我第三次按换档F5时,情况会正常。此时将显示正确的用户界面:-
美孚林
在整个调试过程中,我尝试关闭所有东西(浏览器和节点进程)并反复重新启动以观察行为,但奇怪的是,desktopopen有时不会出现,而它会像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"
}
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)
另外,/pages/_app.js如下所示:-
"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"
}
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)
从“React”导入React
从“下一个/应用程序”导入应用程序
从“../i18n”导入{appWithTranslation}
类MyApp扩展了应用程序{
render(){
const{Component,pageProps}=this.props
返回(
)
}
}
导出默认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);
import React,{useState}来自“React”;
从“下一个/路由器”导入{useRouter};
从“道具类型”导入道具类型
从“../../../../../i18n”导入{i18n,Link,withTranslation}
常量索引=({isMobileView,t})=>{
const router=useRouter();
const[locale]=useState(router.query.locale);
if(i18n.language!==语言环境){
log('将区域设置从'+i18n.language+'切换到'+locale');
i18n.更改语言(区域设置);
}
if(isMobileView){
返回(
{t('mobile')}
{locale}
)
}否则{
返回(
{t('desktop')}
{locale}
)
}
};
Index.getInitialProps=异步函数(上下文){
让isMobileView=(context.req
?context.req.headers['user-agent']
:navigator.userAgent).匹配(
/Android |黑莓| iPhone | iPad | iPod | Opera Mini | IEMobile | WPDesktop/i
)
//将isMobileView作为道具返回组件以供进一步使用。
返回{
isMobileView:布尔值(isMobileView),
需要名称空间:['items'],
}
}
Index.propTypes={
t:PropTypes.func.isRequired,
}
导出带翻译的默认值(“项目”)(索引);
但问题几乎是一样的。唯一的区别是我无法缓存输出为“desktopopen”的时刻
我的问题可以概括为:-
我终于解决了这个问题。问题是我不小心将确定和更改区域设置的逻辑放在了页面组件本身而不是getInitialProps上
import React, { useState } from 'react';
import { useRouter } from 'next/router';
import PropTypes from 'prop-types'
import { i18n, Link, withTranslation } from '../../../../../i18n'
const Index = ({isMobileView, locale, t}) => {
if (isMobileView) {
return (
<div> {t('mobile')}
{locale}
</div>
);
} else {
return (
<div> {t('desktop')}
{locale}
</div>
);
}
};
Index.getInitialProps = async function (context) {
const locale = context.query.locale;
if (i18n.language !== locale) {
console.log('switching locale from ' + i18n.language + ' to ' + locale);
i18n.changeLanguage(locale);
}
const isMobileView = (context.req
? context.req.headers['user-agent']
: navigator.userAgent).match(/Android|BlackBerry|iPhone|iPad|iPod|Opera
Mini|IEMobile|WPDesktop/i);
return {
isMobileView: isMobileView,
locale: locale,
namespacesRequired: ['items']
};
};
Index.propTypes = {
t: PropTypes.func.isRequired,
};
export default withTranslation('items')(Index);
import React,{useState}来自“React”;
从“下一个/路由器”导入{useRouter};
从“道具类型”导入道具类型
从“../../../../../i18n”导入{i18n,Link,withTranslation}
常量索引=({isMobileView,locale,t})=>{
if(isMobileView){
返回(
{t('mobile')}
{locale}
);
}否则{
返回(
{t('desktop')}
{locale}
);
}
};
Index.getInitialProps=异步函数(上下文){
const locale=context.query.locale;
if(i18n.language!==语言环境){
log('将区域设置从'+i18n.language+'切换到'+locale');
i18n.更改语言(区域设置);
}
const isMobileView=(context.req
?context.req.headers['user-agent']
:navigator.userAgent).匹配(/Android |黑莓| iPhone | iPad | iPod | Opera
迷你| IEMobile | WPDesktop/i);
R