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 usereact-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
-
Install:
npm install react-intl --save
. -
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.
-
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 thereact-hot-loader
root componentMain
is<AppContainer>
wrapped, and is a separate from the import fileMain
component.//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 torender()
the outermost return node on the line.// Main.js import { addLocaleData, IntlProvider } from 'react-intl'; /* react-intl imports */ render(){ return ( <IntlProvider> //··· ··· </IntlProvider> ) }
-
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
-
Global current language, and the corresponding text. I.e. arranged
<IntlProvider>
two properties of the componentlocale
andmessages
.// 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> ) }
-
Such basic configuration is complete, you can change
this.state.lang
to change the page language values.// Main.js /** * Change language * @param {String} lang new language */ changeLanguage(lang) { this.setState({ lang: lang }) }
-
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.messages
the value in the corresponding field.
In the international component needs to add text, introducingFormattedMessage
components.import { FormattedMessage } from 'react-intl'; /* react-intl imports */ //... ... <FormattedMessage id="hello" />
The current language is
en
the 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 onMain
the componentsstate.lang
. What if the other components you want to know the current language? One method is directly transferred to theMain
subassembly assemblyprops
, but due to thereact-router
difficult to use this method; then select two methods.
React Intl a API,injectIntl
, can be formatted imperative API injected into any componentprops
of the. Then by that componentthis.props.intl
directly to call some API and attributes, such asthis.props.intl.locale
value is the current language.injectIntl injected into the API assembly props
injectIntl
The 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
messages
the rich text directly contains invalid and will not be resolved. You canvalues
pass by value, plus rich text, such as:<FormattedMessage id="helloSomeone" tagName="div" values={{ name:<p className="name">Evelyn</p> }} />
Note here
name
is 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>
txt
The correspondingmessages
text. When the language isen
to generate results:<input type="button" class="btn-hello" value="Hello!">
At this redefinition
tagName
attribute are invalid.
Reference Reading
- The Best Libraries for React i18n: https://phraseapp.com/blog/posts/react-i18n-best-libraries/
- React Intl wiki: https://github.com/yahoo/react-intl/wiki#getting-started