当前位置: 首页 > 工具软件 > React Intl > 使用案例 >

React Intl 是什么原理?

裴卓君
2023-12-01

react IntL的用途 : React项目国际化,react-intl 这个库提供了针对组件、日期、数字、字符串等多种国际化方法

使用

这里的版本为版本,高版本的用法似乎变了
目前React Intl是FormatJS的一部分,它通过其组件和API提供到React的绑定

  1. 将不同语言的翻译文件放在各自的js文件中,同一处文本的多种语言翻译使用相同的key
//en_US.js
const en_US = {
  hello: 'Hello, world!',
  name: 'my name is {name}'
}    
export default en_US;

//zh_CN.js
const zh_CN = {
  hello: '你好,世界!',
  name: '我的名字是 {name}'
}
export default zh_CN; 
  1. 配置 react-intl 库

react-intl的IntlProvider组件类似redux的Provider组件,需要在全局引入。所以我们封装一下Intl.jsx组件,将redux和IntlProvider相结合

import React, { Component } from 'react';
import { addLocaleData, IntlProvider } from 'react-intl';
import { connect } from 'react-redux';
import zh_CN from './locale/lang/zh_CN';
import en_US from './locale/lang/en_US.js';
import zh from 'react-intl/locale-data/zh';
import en from 'react-intl/locale-data/en';

addLocaleData([...zh,...en]);

class Inter extends Component {
  render() {
    let { locale, localeMessage, children } = this.props;
    return (
      <IntlProvider key={locale} locale={locale} messages={localeMessage}>
        {children}
      </IntlProvider>
    )
  }
};
function chooseLocale(val) {
  let _val = val || navigator.language.split('_')[0];
  switch (_val) {
    case 'en':
      return en_US;
    case 'zh':
      return zh_CN;
    default:
      return en_US;
  }
}

const mapStateToProps = (state, ownProps) => ({
  locale: state.root.language,
  localeMessage: chooseLocale(state.root.language)
});

let Intl = connect(mapStateToProps)(Inter);

export default Intl;

redux相关代码可以忽略,重点关注react-intl的配置

这里有一个很关键的地方,即key属性。IntlProvider中的属性变更并不会触发FormattedMessage重新渲染,刚开始想要forceUpdate强制更新组件,后来上网查了一个解决方案,在组件中加入key,就能解决这个问题

  1. 然后使用这个组件
    <Intl>
      <App />
    </Intl>
import { FormattedMessage } from 'react-intl';
//。。。
class App extends Component {
  changeLanguage() {
    let lang = this.props.locale;
    lang = lang === 'zh' ? 'en' : 'zh';
    this.props.changeLanguage(lang);
  }
  render() {
    const { locale } = this.props;
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">
            <FormattedMessage
              id="hello"
            />
          </h1>
        </header>
        <p className="App-intro">
          <FormattedMessage
            id="name"
            values={{ name: <b>{'carroll'}</b> }}
          />
        </p>
        <button onClick={() => this.changeLanguage()}>{locale === 'zh' ? '切换英文' : 'change chinese'}</button>

      </div>
    );
  }
}

React Intl Components文档

关于国际化

国际化方案很多,列举主要的几种:

  • 编译期间转化:例如wepack的i18n-webpack-plugin,打包的时候对_(‘key’)进行转义
  • 运行期间转化:react-intl等,把中文词条写成intl.get()的方式,在运行时获取中文文案
  • wordpress的getText方案:gettext是一个filter 钩子, 用来替换和本地化翻译文本, 替换 __()、_e()、_x()、_ex() 和 _n() 函数包含的文本

React Intl 原理

做国际化就类似于字体文件,通过切换语言,加载不同语言包到本地

实现原理和react-redux的实现原理类似,最外层包一个Provider,利用getChildContext,将intlConfigPropTypes存起来,在FormattedMessage、FormattedNumber等组件或者调用injectIntl生成的高阶组件中使用,来完成国际化的。

就前端国际化来说:

核心步骤有两步:

  • 创建资源文件,以 key-value 方式存储
  • 加载资源文件,将页面上 key 的内容替换为相关 value

所以就React Int的使用层面来说不同语言的翻译文件 就属于创建资源文件,React Int的组件IntlProvider 就相当于加载资源文件,id提供映射

更多用法看官方文档去吧,哈哈哈,我没咋做过这方面,自嗨也没有自嗨过,国际化好多东西呢,以后用到了再详细玩一下,光React Intl 用法也有好多,react国际化的库也不止React Intl

 类似资料: