本次记录一下在处理react项目中实现中英文切换功能,实现的过程并没有什么难度,主要记录一下过程以及再实现过程中出现的问题,并且当前实现国际化还有一些缺陷。
环境
react 16.8.6
react-i18next 11.8.10
antd 3.20.7
中英文切换实现
antd 中中英文切换
因为当前的工程中组件采用的antd
,在使用的时间选择器组件也需要做一下中英文切换功能。 采用antd提供的组件 LocaleProvider
包裹 App
组件进行实现
js
<LocaleProvider locale={getLanguage()}>
<BrowserRouter>
<App />
</BrowserRouter>
</LocaleProvider>
getLanguage
函数用来获取本地设置的语言(中文/英文),目前是将用户选择的语言存储在了本地中。
js
import zh_CN from "antd/es/locale-provider/zh_CN";
import en_US from "antd/es/locale-provider/en_US";
function getLanguage() {
if (!localStorage.getItem("language")) {
// 本地存储中没有文本状态,默认为 中文
localStorage.setItem("language", 'zh_CN');
}
// 根据 返回的字符串 返回相应的 antd 语言包
if (localStorage.getItem("language") === 'zh_CN') {
return zh_CN;
} else {
return en_US;
}
}
antd 组件中有相关的语音包,导入即可。
reac-i18next
的使用
接下来就是工程中react-i18next
的使用了,我们通过使用该组件,搭配其withTranslation
高阶组件,将我们的页面以及自定义的组件进行包裹来实现中英文的切换。
语音包
当然我们要实现中英文切换的话,肯定要有两套语言包即:中文、英文,通过当前用户选择的方式进行动态的切换。 我们可以在工程中创建 locales 文件夹,包含en_US 与zh_CN对应英文、中文两种语言。然后在 i18n.js 中引入
zh_js
js
export default {
registered: '注册',
}
en.js
js
export default {
registered: 'registered',
}
i18n.js 相关代码
下面是 i18n.js 相关代码的实现
js
//i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import zh_CN from './locales/zh_CN/zh';
import en_US from './locales/en_US/en';
const resources = {
zh_CN: {
translation: {
...zh_CN,
}
},
en_US: {
translation: {
...en_US,
}
},
};
// 获取本地 language 语言
function getLanguage() {
if (!localStorage.getItem("language")) {
// 本地存储中没有文本状态,默认为 中文
localStorage.setItem("language", 'zh_CN');
}
return localStorage.getItem("language")
}
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources,
lng: getLanguage(),
keySeparator: false, // we do not use keys in form messages.welcome
interpolation: {
escapeValue: false, // react already safes from xss
},
});
export default i18n;
我们在工程中创建i18n.js
文件,并且在工程的index.js
中引入。
js
import './i18n';
ReactDOM.render((
<LocaleProvider locale={getLanguage()}>
<BrowserRouter>
<App />
</BrowserRouter>
</LocaleProvider>
), document.getElementById('root'));
组件、页面中的使用
我们只需要引入withTranslation
对当前的组件进行包裹,然后通过props
中接收t
,然后将对应的中文替换为{t('registered')}
即可。
类组件:
js
import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
class Demo extends Component {
constructor(props) {
super(props);
}
let { t } = this.props;
render() {
return(
<div>
{t('registered')}
</div>
)
}
}
export default withTranslation()(Demo);
函数组件:
js
import React, { useEffect, useState } from 'react';
import { withTranslation } from 'react-i18next';
function Demo(props) {
let { t } = props;
return(
<div>
{t('registered')}
</div>
)
}
export default withTranslation()(Demo);
中英文切换选项
一般我们都是在 Header
组件中提供切换功能。
js
// 中英文切换下拉菜单
const changeLanguageMenu = (
<Menu key="11">
<Menu.Item key="11_1" onClick={() => this.changeLanguage('zh_CN')}>
中文
</Menu.Item>
<Menu.Item key="11_2" onClick={() => this.changeLanguage('en_US')}>
English
</Menu.Item>
</Menu>
)
js
// 切换中英文
changeLanguage = (mark) => {
// 当选择的 与本地存储的语言类型不同的时候,进行语言的切换
if (mark === localStorage.getItem('language')) {
return;
}
// mark=zh 中文 (默认中文)
// mark=en 英文
if (mark === 'zh_CN') {
localStorage.setItem("language", 'zh_CN');
} else if (mark === 'en_US') {
localStorage.setItem("language", 'en_US');
}
window.location.reload()
}
至此,项目中我们已经实现了中英文切换的功能。
注意事项
当然我们在使用 withTranslation
包裹相关组件的时候,也需要注意。因为我们有时候会通过ref
获取组件实例调用一些方法。但是当我们直接withTranslation()(Demo)
这样就会出现一些问题。
我们可以采用以下方式进行解决:
js
export default withTranslation('translation', { withRef: true })(Demo);
总结
到这里,该功能以及在实现功能中出现的问题都已经讲解清晰了。当然这只是实现国际化的最基础的一种方式,该方式还有很多缺点,例如:语言包的维护,在后续开发维护拓展的过程中还是有所不足,当然基础的使用是能够满足的。
让我们在技术开发的路上不断前行,与君共勉!!!