如有错误,请留言指出,感谢您的反馈
1. react-i18next
的使用
优点:使用hook方式,简单易用。提供方法更改语言,不用手动实现
-
安装插件
npm install react-i18next i18next --save // 或者 yarn add react-i18next i18next
-
在
assets
新建locales
文件夹,存放locale语言包// locales/en-US.json { "hello":"Hello" } // locales/zh-CN.json { "hello":"你好" }
-
在
locales
下新建resources.js
import enUS from './en_US.json'; import zh from './zh_CN.json'; const resources = { 'en-US': { translation: enUS, }, 'zh-CN': { translation: zh, }, zh: { translation: zh, }, }; export default resources;
-
在
src
目录下新增i18n.ts
import { initReactI18next } from 'react-i18next'; import i18n from 'i18next'; import resources from 'assets/locales/resources.js'; // the translations // (tip move them in a JSON file and import them, // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui) let localLang = sessionStorage.getItem('lang'); const browserLang = navigator.language; if (!localLang) { localLang = browserLang === 'zh-CN' ? 'zh-CN' : 'en-US'; } i18n .use(initReactI18next) // passes i18n down to react-i18next .init({ resources, lng: localLang, // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources // you can use the i18n.changeLanguage function to change the language manually: https://www.i18next.com/overview/api#changelanguage // if you're using a language detector, do not define the lng option interpolation: { escapeValue: false, // react already safes from xss }, }); export default i18n;
-
在
main.ts/index.ts
中全局导入i18n.ts
import './index.less'; import App from './App'; import React from 'react'; import ReactDOM from 'react-dom'; import './i18n' // 新增:导入i18n ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root'), );
-
在要使用国际化的页面使用
useTranslation
hookimport { useTranslation } from 'react-i18next'; const Welcome = () => { const [t, i18n] = useTranslation() return ( <div> 国际化测试数据: {t('hello')} </div> ); }; export default Welcome; // 页面结果显示: 中文-> 国际化测试数据:你好;英文:-> 国际化测试数据:Hello
-
语言包切换
在需要执行切换的界面导入``useTranslation
hook,并绑定事件
toggleI18n`// 顶部导入 useTranslation import { useTranslation } from 'react-i18next'; // 组件内部使用hook const [t, i18n] = useTranslation() // 在事件方法中使用i18n.changeLanguage()方法 const toggleI18n = () => { const locale = i18n.language === "zh-CN" ? "en-US" : "zh-CN"; i18n.changeLanguage(locale) }
简单的例子:
import React from 'react'; // 顶部导入 useTranslation import { useTranslation } from 'react-i18next'; const Layout: FC<any> = (props: PropsWithChildren<any>) => { // 组件内部使用hook const [t, i18n] = useTranslation(); // 在事件方法中使用i18n.changeLanguage()方法 const toggleI18n = () => { const locale = i18n.language === "zh-CN" ? "en-US" : "zh-CN"; i18n.changeLanguage(locale) } return ( <div> <button onClick={toggleI18n}> i18n切换 </button> </div> ); }; export default Layout;
2. React-intl-universal
优点:配置简单、易上手、迁移简单、支持变量翻译
缺点:切换语言时较为繁琐
-
安装插件
npm install react-intl-universal --save // or yarn add react-intl-universal -s
-
准备
langs
语言包,在src
文件夹下新建assets/locales
,在locales文件夹下新建langs
文件夹// zh-CN.ts const zh_CN = { hello: "你好" } export default zh_CN; // en-US.ts const en_US = { hello: "Hello" } export default en_US
-
编写配置文件,在locales中增加index.ts文件
import intl from 'react-intl-universal'; import zh_CN from './langs/zh_CN' import en_US from './langs/en_US' // common locale data import 'intl/locale-data/jsonp/en.js' import 'intl/locale-data/jsonp/zh.js' // app locale data const locales = { "en-US": en_US, "zh-CN": zh_CN }; const locale = navigator.language; intl.init({ currentLocale: locale, // TODO: determine locale here locales, }) .then(() => { // After loading CLDR locale data, start to render console.log("Initialize the language pack!"); });
-
在全局引入配置文件,在
main.ts/index.ts
中全局引入import './index.less'; import App from './App'; import React from 'react'; import ReactDOM from 'react-dom'; import './assets/locales' ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root'), );
-
封装方法(可省略),在
locales
下新建utils.ts
文件import intl from 'react-intl-universal' const options = intl.getInitOptions(); /** * Change Language * @param history The history of react, you can use <useHistory> to get. * @param locale Language to be convered */ export function setLocale(history: any, locale: string) { intl.init({ currentLocale: locale, locales: options.locales }).then(() => { history.push(history.location.pathname) }) } /** * Get the value with key from the locales pack * @param key : The key in locales pack * @returns The value find by the key in locales */ export function get(key: string) { return intl.get(key); }
-
在页面中使用
// 要使用国际化的页面 import React from 'react'; import http from 'services' import { get } from 'assets/locales-universal/utils' const Welcome = () => { return ( <div> {get("name")} </div> ); }; export default Welcome;
-
如何手动切换语言
// 需要切换的页面 // 顶部导入自定义方法setLocale import { setLocale } from 'assets/locale-universal/utils'; // 使用自定义方法设置语言 const toggleI18n = () => { const locale = locale==="zh-CN"?"en-US":"zh-CN"; setLocale(locale) }
简单的例子:
import React from 'react'; // 顶部导入自定义方法setLocale import { setLocale } from 'assets/locale-universal/utils'; const Layout: FC<any> = (props: PropsWithChildren<any>) => { const [locale, setLocale] = useState("zh-CN"); // 在事件方法中使用自定义方法setLocale方法 const toggleI18n = () => { const locale = locale==="zh-CN"?"en-US":"zh-CN"; setLocale(locale) } return ( <div> <button onClick={toggleI18n}> i18n切换 </button> </div> ); }; export default Layout;
3. react-intl
-
安装依赖
npm install react-intl --save // or yarn add react-intl
-
准备langs语言包,在
src/locales
下新建langs
文件夹// zh-CN.ts const zh_CN = { hello: "你好" } export default zh_CN; // en-US.ts const en_US = { hello: "Hello" } export default en_US
-
在locales文件夹下新建I18n.tsx
import React, { FC } from 'react' import { FormattedMessage, useIntl } from 'react-intl' interface IProps { children: any, value?: any defMsg?: string } const I118n: FC<IProps> = ({ children, value, defMsg }) => { // isAuto:为true时,将自动查找value在语言包里的key值,将其置于组件的id中(有待完善) const isAuto = false; const intl = useIntl(); return ( <div> <FormattedMessage id={ children} defaultMessage={defMsg} values={value} /> </div> ) } export default I118n
-
在locales文件夹下新建Intl.tsx
import React, { useState } from 'react' import { createIntl, MessageFormatElement, RawIntlProvider } from 'react-intl' import { langs } from './lang' const Intl = (props: any) => { const [locale, setLocale] = useState(navigator.language) // 用于存储选中的语言,默认为浏览器的语言 let messages: Record<string, string> | Record<string, MessageFormatElement[]> = langs[locale]; const intl = createIntl({ locale, messages, setLocale }) return ( <RawIntlProvider value={intl}> {props.children} </RawIntlProvider> ) } export default Intl;
-
编写
utils.tsx
,在locales
文件夹下新建utils.tsx
// 由于在这个工具包里使用了tsx,因此要使用.tsx后缀 import React from 'react' import I18n from './I18n' /** * Get value from locales pack * @param key The key of locales pack * @param value The value of Translation * @returns Node */ export function get(key: string, value?: any) { return <I18n value={value}>{key}</I18n> }
-
在
mian.tsx/index/tsx
中将<App/>
包裹起来import './index.less'; import App from './App'; import React from 'react'; import ReactDOM from 'react-dom'; import Intl from './assets/locale-intl/Intl' ReactDOM.render( <React.StrictMode> <Intl> <App /> </Intl> </React.StrictMode>, document.getElementById('root'), );
-
在需要国际化的页面使用
import React from 'react'; import http from 'services' import { get } from 'assets/locales/utils' const Welcome = () => { return ( {getIntl("name", { name: "zhangsan " })} ); }; export default Welcome;
-
如何切换语言
// 由于react-intl没有提供切换语言的方法(可能是我没找到),因此在编写 Intl.tsx 时向里面注入了一个setLocale()方法,可以使用这个方法实现语言的切换 // 需要切换的页面 // 顶部导入 useIntl hook import { useIntl } from 'react-intl'; const Layout = ()=>{ // 实例一个intl const intl = useIntl() // 使用自定义方法设置语言 const toggleI18n = () => { const locale = locale==="zh-CN"?"en-US":"zh-CN"; intl.setLocale(locale) } return ( // ... <button onClick={toggleI18n}> i18n切换 </button> ) } export default Layout
4. 三者的对比
名称 实现方式 无感刷新 手动语言切换 迁移难度 使用方式 react-intl 使用hook 支持 注入setLocale实现 需要包裹 <App />组件
组件 react-i18next 使用hook 支持 自带changeLanguage()方法 在入口文件引入 函数 react-intl-universal 使用内置方法 不支持 通过刷新地址栏实现 在入口文件引入 函数