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
–これは翻訳の略です。 を見るのが一般的です t
i18nextドキュメントで機能し、この投稿で使用されていることがわかります。
i18nextは多くのフレームワークで動作するように設計されていますが、この投稿では、i18nextを使用してReactアプリを国際化する方法に焦点を当てます。
Reactでi18nextを使用するには、 t
国際化が必要なコンポーネントで機能を利用できるようにする必要があります。 これはさまざまな方法で実行できます。 以下にいくつかのデモを行います。
手動統合
i18nextを使用する前に、構成する必要があります。 この投稿の例で使用されている構成は次のとおりです。 Reactはすでに値のエスケープを処理しているため、値のエスケープをオフにし、現在の言語を英語に設定し、2つの言語(英語とスペイン語)の翻訳をハードコードします。 その他のオプションについては、i18next構成を参照してください。
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
手動統合は、事前に構成されたi18nextのインスタンスをインポートすることから始まります。 t
関数。
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を参照してください。