Before you start, check out The Best Libraries for React i18n. I chose React-i18Next because it seemed easy to use. However, there were a lot of problems with it, and I didn’t want to waste any more time, so I switched to react-INTl. It proved wise to change the plan in time.

React Intl

React Intl Internationalizes the React component and provides the React component and API to format dates, numbers, and strings (including singular and plural numbers and translations). This time it will only be used for text translation.

usage

  1. NPM install react-intl –save

  2. Load locale data. React Intl relies on this data to support singular and complex numbers and relative time formatting.

    // Main.js
    import { addLocaleData } from 'react-intl'; /* react-intl imports */
    import en from 'react-intl/locale-data/en';
    import zh from 'react-intl/locale-data/zh'; addLocaleData([...en, ...zh]); // Introduce multilingual dataCopy the code

    I only used the text translation function, thinking I wouldn’t need to load the data, but it turned out to be a must. Otherwise an error will be reported:

    [React Intl] Missing locale data for locale: "zh". Using default locale: "en" as fallback.
    Copy the code
  3. Use the

    component to wrap the root component that needs to be internationalized, and the component tree will then be in the configured I18N context. Since the project uses react-hot-loader, the root component Main is wrapped in

    and imports Main from a separate file.

    //app.js
    import { AppContainer } from 'react-hot-loader'
    import Main from './components/Main'/ /... . const render = Component => { ReactDOM.render( <AppContainer> <Component /> </AppContainer>, document.getElementById('app')
        )
    }
    render(Main);
    Copy the code

    Use the

    component directly in main.js. Just add it to render() to return the outermost layer of the node.

    // Main.js
    import { addLocaleData, IntlProvider } from 'react-intl'; /* react-intl imports */
    render() {return(<IntlProvider> //··· · </IntlProvider>)}Copy the code
  4. Add text for multiple languages. For example, to support Both Chinese and English, two new files can be created for convenient maintenance:

    // en_US.js
    const en_US = {
        hello: "Hello!", / /... . }export default en_US;
    Copy the code
    // zh_CN.js
    const zh_CN = {
        hello: "Hello!, / /... . }export default zh_CN;
    Copy the code

    We then introduce these two variables in main.js.

    // Main.js
    import zh_CN from ".. /locale/zh_CN"     // import defined messages in Chinese
    import en_US from ".. /locale/en_US"     // import defined messages in English
    Copy the code
  5. Globally configures the current language and corresponding text. That is, configure the locale and messages properties of the

    component.

    // Main.js
    render() {let messages = {}
        messages['en'] = en_US;
        messages['zh'] = zh_CN;
        return(<IntlProvider locale={this.state.lang} messages={messages[this.state.lang]}> //··· ·· </IntlProvider>)}Copy the code
  6. This completes the basic configuration and allows you to change the page language by changing the value of this.state.lang.

    // Main.js
    /**
     * Change language
     * @param {String} lang new language
     */
    changeLanguage(lang) {
        this.setState({
            lang: lang
        })
    }
    Copy the code
  7. Next, add the translated text to the page. Basically you only need to use one component:
    . By default, this component generates a
    with the translated text, which is the value of the corresponding field in messages. In the component where you want to add internationalized text, introduce the FormattedMessage component.

    import { FormattedMessage  } from 'react-intl'; /* react-intl imports */ //... . <FormattedMessage id="hello" />
    Copy the code

    If the current language is EN, the following result is generated:

    <span>Hello!</span>
    Copy the code

    At this point, basic internationalization is achieved.

further

  • Add variables to the text.

    // en_US.js
    const en_US = {
        helloSomeone: "Hello, {name}!"
    }
    // zh_CN.js
    const zh_CN = {
        helloSomeone: "{name}, hello!"
    }
    Copy the code
    <FormattedMessage id="helloSomeone" values={{name:"Evelyn"}} / >Copy the code
  • In any component, gets the current page language. Based on the above configuration, you can see whether the current language is English or Chinese, depending on the state.lang of the Main component. What if you want to know the current language among other components? The first method is to pass props to the subcomponents of the Main component directly, but this method is not convenient because the React router is used. So I chose method two. React Intl provides an API, injectIntl, that can inject an imperative formatting API into the props of any component. You can then call some APIS and properties directly from that component via this.props. Intl, for example, the value of this.props. Intl. Locale is the current language.

InjectIntl can be used as an example in the official documentation, which is not detailed here.

  • Custom tag name, do not generate . Such as generating

    .

    <FormattedMessage id="hello" tagName="p" />
    Copy the code
  • The generated text contains rich text. Containing rich text directly in messages is invalid and will not be parsed. You can pass values with rich text, such as:

    <FormattedMessage 
      id="helloSomeone" 
      tagName="div" 
      values={{
        name:<p className="name">Evelyn</p>
      }} />
    Copy the code

    Note that name is not a string, but a React element. The result is:

    <div>Hello, <p class="name">Evelyn</p>!</div>
    Copy the code
  • ** Custom generated nodes. ** For example, generate a button:

    <FormattedMessage id='hello'>
        {(txt) => (
          <input type="button"
            className="btn-hello"
            onClick={this.handleClickHello.bind(this)}
            value={txt} />
        )}
    </FormattedMessage>
    Copy the code

    TXT corresponds to the text in messages. Results when the language is en:

    <input type="button" class="btn-hello" value="Hello!">
    Copy the code

    It is invalid to define the tagName attribute again.

Refer to the reading

  1. The Best Libraries for The React i18n: phraseapp.com/blog/posts/…
  2. The React Intl wiki: github.com/yahoo/react…