react 主流国际化库的使用与对比

如有错误,请留言指出,感谢您的反馈

1. react-i18next的使用

优点:使用hook方式,简单易用。提供方法更改语言,不用手动实现

  1. 安装插件

    npm install react-i18next i18next --save
    // 或者
    yarn add react-i18next i18next
    
  2. assets新建locales文件夹,存放locale语言包

    // locales/en-US.json
    {
    	"hello":"Hello"
    }
    // locales/zh-CN.json
    {
    	"hello":"你好"
    }
    
  3. 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;
    
  4. 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;
    
  5. 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'),
    );
    
  6. 在要使用国际化的页面使用useTranslation hook

    import { useTranslation } from 'react-i18next';
    
    const Welcome = () => {
      const [t, i18n] = useTranslation()
      return (
        <div>
         国际化测试数据: {t('hello')}
        </div>
      );
    };
    export default Welcome;
    
    // 页面结果显示: 中文-> 国际化测试数据:你好;英文:-> 国际化测试数据:Hello
    
  7. 语言包切换

    在需要执行切换的界面导入``useTranslationhook,并绑定事件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

优点:配置简单、易上手、迁移简单、支持变量翻译

缺点:切换语言时较为繁琐

  1. 安装插件

    npm install react-intl-universal --save
    // or 
    
    yarn add react-intl-universal -s
    
  2. 准备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
    
  3. 编写配置文件,在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!");
      });
    
  4. 在全局引入配置文件,在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'),
    );
    
  5. 封装方法(可省略),在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);
    }
    
  6. 在页面中使用

    // 要使用国际化的页面
    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;
    
    
  7. 如何手动切换语言

    // 需要切换的页面
    // 顶部导入自定义方法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

  1. 安装依赖

    npm install react-intl --save
    // or
    yarn add react-intl
    
  2. 准备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
    
  3. 在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
    
  4. 在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;
    
    
  5. 编写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>
    }
    
  6. 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'),
    );
    
  7. 在需要国际化的页面使用

    import React from 'react';
    import http from 'services'
    import { get } from 'assets/locales/utils'
    
    const Welcome = () => {
    
      return (
          {getIntl("name", { name: "zhangsan " })}
      );
    };
    
    export default Welcome;
    
    
  8. 如何切换语言

    // 由于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使用内置方法不支持通过刷新地址栏实现在入口文件引入函数
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值