Use react-intl achieve international component React

Before you begin, first understand the most commonly used international plug React: at The Best React the Libraries for i18n . Because it looks relatively simple to use, I first chose react-i18next. But many problems encountered in the use, do not want to waste time, so instead use react-intl. It proved to be wise in time to change the program.

React Intl

React Intl international React assembly for providing React component and the API to format dates, numbers, strings (including single and plural translation). The only use it to implement text translation.

usage

  1. Install:npm install react-intl --save .

  2. Loading locale data. React Intl rely on these data to support single and plural relative time formatting functions.

    // 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]);  // 引入多语言环境的数据  
    

    Although I only want to add the translated text, that there is no need to load the data, but later found that this is a necessary step. Or will be error:

    [React Intl] Missing locale data for locale: "zh". Using default locale: "en" as fallback.
    
  3. Use <IntlProvider>components need to achieve international parcel of the root component, i18n context tree after this component will be in the configuration of the.
    Used in the project since the react-hot-loaderroot component Mainis <AppContainer>wrapped, and is a separate from the import file Maincomponent.

    //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);
    

    Main.js then used directly in the <IntlProvider>assembly. Add it to render()the outermost return node on the line.

    // Main.js
    import { addLocaleData, IntlProvider } from 'react-intl'; /* react-intl imports */
    render(){
        return (
            <IntlProvider>
              //··· ···
            </IntlProvider>
        )
    }
    
  4. Add the corresponding text in multiple languages. For example, to support Chinese and English, in order to facilitate maintenance after, can create two files:

    // en_US.js
    const en_US = {
        hello: "Hello!",
        //... ...
    }
    export default en_US;
    
    // zh_CN.js
    const zh_CN = {
        hello: "你好!",
        //... ...
    }
    export default zh_CN;
    

    These two variables are then introduced in Main.js in.

    // 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
    
  5. Global current language, and the corresponding text. I.e. arranged <IntlProvider>two properties of the component localeand messages.

    // 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>
        )
    }
    
  6. Such basic configuration is complete, you can change this.state.langto change the page language values.

    // Main.js
    /**
     * Change language
     * @param {String} lang new language
     */
    changeLanguage(lang) {
        this.setState({
            lang: lang
        })
    }
    
  7. Next, add the translated text into the page.
    Only you need to use a basic components: <FormattedMessage>. This component generates a default <span>, the content is translated text, i.e. messagesthe value in the corresponding field.
    In the international component needs to add text, introducing FormattedMessagecomponents.

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

    The current language is enthe time to produce results:

    <span>Hello!</span>
    

    Here, the basic international realized.

Further

  • Add text variables .

    // en_US.js
    const en_US = {
        helloSomeone: "Hello, {name}!"
    }
    // zh_CN.js
    const zh_CN = {
        helloSomeone: "{name},你好!"
    }
    
    <FormattedMessage id="helloSomeone" values={{name:"Evelyn"}}/>
    
  • In any component, to get the current page language .
    Based on the above configuration, you can see that the current language is English or Chinese, depending on Mainthe components state.lang. What if the other components you want to know the current language? One method is directly transferred to the Mainsubassembly assembly props, but due to the react-routerdifficult to use this method; then select two methods.
    React Intl a API, injectIntl, can be formatted imperative API injected into any component propsof the. Then by that component this.props.intldirectly to call some API and attributes, such as this.props.intl.localevalue is the current language.

    injectIntl ​​injected into the API assembly props

     

injectIntlThe method of use may look official document example , not repeat them here.

  • Custom label name is not generated <span>. For example, generation <p>.

    <FormattedMessage id="hello" tagName="p" />
    
  • The resulting text contains rich text . In messagesthe rich text directly contains invalid and will not be resolved. You can valuespass by value, plus rich text, such as:

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

    Note here nameis not a string, but React elements. The results are:

    <div>Hello, <p class="name">Evelyn</p>!</div>
    
  • Custom node generated. For example, to generate a button:

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

    txtThe corresponding messagestext. When the language is ento generate results:

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

    At this redefinition tagNameattribute are invalid.

Reference Reading

  1. The Best Libraries for React i18n: https://phraseapp.com/blog/posts/react-i18n-best-libraries/
  2. React Intl wiki: https://github.com/yahoo/react-intl/wiki#getting-started

Guess you like

Origin blog.csdn.net/qq_36742720/article/details/90574070