递归组件多语言传递问题

大家都知道使用多语言在配置好之后只需要在相应文件里

1
2
3
4
5
6
7
8
9
10
11
12
13
...
import { translate } from 'react-i18next';

@translate()
export default class PersonInfo extends React.Component {
render() {
let { t } = this.props;
return (
<div>{t('example.key')}</div>
)
}
}
...

但是我在给项目加入多语言的时候,遇到一个很奇怪的问题,有个文件加入多语言后一直会报

Uncaught (in promise) TypeError: t is not a function

但是在其他文件里多语言都是可以正常使用的,已经通过

import { translate } from 'react-i18next';

引入了 translate ,@translate 装饰器也已经加上了,明明是和其他文件一样的写法,为什么只有它找不到t呢?

我尝试在控制台打印 t 的类型,结果如下

1
2
3
4
5
6
7
console.log(typeof t);
// function
// undefined
// undefined
// function
// function
...

我发现有的是 function ,有的是 undefined

这时候需要解释一下我的接口结构和代码结构,接口结构是无限嵌套的关系,所以在我的代码里是使用组件递归的方式来实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
import { translate } from 'react-i18next';

@translate()
export default class PersonInfo extends React.Component {
render() {
let { t } = this.props;
return (
<div>
<div>{t('example.i18n.key')}</div>
<If condition={data.child !== null}>
<PersonInfo data={data.child} />
</If>
</div>
)
}
}
...

在对比控制台的打印结果和我的模拟数据之后,我发现 undefined 的都是子集合,也就是接口里的 child 字段,既然他们找不到t这个函数,那我就手动的传递过去试一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
render() {
let { t } = this.props;
return (
<div>
<div>{t('example.i18n.key')}</div>
<If condition={data.child !== null}>
<PersonInfo t={t} data={data.child} />
</If>
</div>
)
}
...

我在自调用的PersonInfo组件里手动传递了t过去

1
<PersonInfo t={t} data={data.child} />

果然,该页面多语言正常了。react-i18next并不能把 t 传递给递归的组件,需要开发者手动去传递。