ますます多くのアプリがグローバル市場向けに設計されています。つまり、アプリはさまざまな言語や方言を使用するオーディエンスのために機能する必要があります。 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>
    )
  }
}

上記のコードの動作例を参照してください。

言語の変更後にコンポーネントが再レンダリングされないという問題を修正しましたが、多くの定型コードを導入しました。

  1. 2つのライフサイクルメソッド(componentDidMountおよびcomponentWillUnmount)が追加されました。 (つまり、機能コンポーネントからクラスコンポーネントに切り替える必要がありました。)

  2. 言語が変更されたことをReactに通知できるように、イベントリスナーを追加しました。

  3. コンポーネントを再レンダリングするメカニズムが導入されました。 上記の例では、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を参照してください。