Reactとi18nextを備えたI18n
ますます多くのアプリがグローバル市場向けに設計されています。つまり、アプリはさまざまな言語や方言を使用するオーディエンスのために機能する必要があります。 Reactには国際化(i18n)が組み込まれていませんが、特にi18nextの助けを借りて、アプリを国際化することは難しくありません。
i18next は、JavaScriptで記述されたi18nフレームワークです。 これは、補間、フォーマット、および複数形とコンテキストの処理の標準i18n機能を提供します。
i18nextの30,000フィートのビューは、キーといくつかのオプションを受け取り、現在の言語の値を返す関数を提供することです。
以下は、オプションなしで単純なキーを使用して前述の関数を使用する簡単な例です。
i18n.t('error') // 'An error occurred' in English and // 'Ocurrió un error' in Spanish.
この関数はアプリ内で何度も呼び出される可能性があるため、i18nextの作成者は、翻訳の略であるt
という短縮名を選択しました。 i18nextのドキュメントでt
関数を確認するのが一般的であり、この投稿で使用されていることがわかります。
i18nextは多くのフレームワークで動作するように設計されていますが、この投稿では、i18nextを使用してReactアプリを国際化する方法に焦点を当てます。
Reactでi18nextを使用するには、国際化が必要なコンポーネントでt
機能を使用できるようにする必要があります。 これはさまざまな方法で実行できます。 以下にいくつかのデモを行います。
手動統合
i18nextを使用する前に、構成する必要があります。 この投稿の例で使用されている構成は次のとおりです。 Reactはすでに値のエスケープを処理しているため、値のエスケープをオフにし、現在の言語を英語に設定し、2つの言語(英語とスペイン語)の翻訳をハードコードします。 その他のオプションについては、i18next構成を参照してください。
モジュール:i18n.js
import i18next from 'i18next'; i18next .init({ interpolation: { // React already does escaping escapeValue: false, }, lng: 'en', // 'en' | 'es' // Using simple hardcoded resources for simple example resources: { en: { translation: { age: { label: 'Age', }, home: { label: 'Home', }, name: { label: 'Name', }, }, }, es: { translation: { age: { label: 'Años', }, home: { label: 'Casa', }, name: { label: 'Nombre', }, }, }, }, }) export default i18next
手動統合は、t
関数を提供するi18nextの事前構成されたインスタンスをインポートすることから始まります。
import React from 'react'; // Import a pre-configured instance of i18next import i18n from './i18n'; function Gator({ gator }) { return ( <div className="Gator"> <label>i18n.t('name.label')</label> <span>{ gator.name } 🐊</span> <label>i18n.t('age.label')</label> <span>{ gator.age }</span> <label>i18n.t('home.label')</label> <span>{ gator.home }</span> </div> ) }
上記の例では現在の言語(英語)を使用してラベルをレンダリングしますが、Reactは言語がいつ変更されたかを判断する方法をまだ知らないため、言語が変更されてもラベルは更新されません。 それでは、言語が変更されたときにコンポーネントを再レンダリングするようにコードを微調整しましょう。
import React from 'react'; // Import a pre-configured instance of i18next import i18n from './i18n'; class Gator extends React.Component { constructor(props) { super(props) this.state = { lng: 'en' } this.onLanguageChanged = this.onLanguageChanged.bind(this) } componentDidMount() { i18n.on('languageChanged', this.onLanguageChanged) } componentWillUnmount() { i18n.off('languageChanged', this.onLanguageChanged) } onLanguageChanged(lng) { this.setState({ lng: lng }) } render() { let gator = this.props.gator, lng = this.state.lng return ( <div> <label>{ i18n.t('name.label', { lng }) }</label> <span>{ gator.name } 🐊</span> <label>{ i18n.t('age.label', { lng }) }</label> <span>{ gator.age }</span> <label>{ i18n.t('home.label', { lng }) }</label> <span>{ gator.home }</span> </div> ) } }
上記のコードの動作例を参照してください。
言語の変更後にコンポーネントが再レンダリングされないという問題を修正しましたが、多くの定型コードを導入しました。
- 2つのライフサイクルメソッド(componentDidMountおよびcomponentWillUnmount)を追加しました。 (つまり、機能コンポーネントからクラスコンポーネントに切り替える必要がありました。)
- 言語が変更されたことをReactに通知できるように、イベントリスナーを追加しました。
- コンポーネントを再レンダリングするメカニズムが導入されました。 上記の例では、stateが使用されています。 別の方法は、言語が変更された後にforceUpdateを呼び出すことです。
もっと簡単な方法はありますか? はいあります!
react-i18nextバインディング
幸い、バインディングを使用するより簡単な方法があります:react-i18next。
import React from 'react'; import { I18n } from 'react-i18next'; // Import a pre-configured instance of i18next import i18n_unused from './i18n'; function Gator({ gator }) { return ( <I18n> { (t) => { return ( <div> <label>{ t('name.label') }</label> <span>{ gator.name } 🐊</span> <label>{ t('age.label') }</label> <span>{ gator.age }</span> <label>{ t('home.label') }</label> <span>{ gator.home }</span> </div> ) } } </I18n> ) }
i18nextのReactバインディングは、I18n
コンポーネントを提供します。 子として単一の関数式を期待します。 この関数には、t
関数が渡されます。 (コンポーネントの子としての関数式の使用は、子としての関数パターンとして知られています。)
はるかに簡単です! 上記のコードの動作例を参照してください。
したがって、構成、より高度な変換、およびその他のバインディングオプションの詳細については、i18nextおよびreact-i18nextを参照してください。