FrontEnd

react-intl (Format.js) を使ってi18n対応

投稿日:2021年12月6日 更新日:

はじめに

最近、Reactを勉強しているので、しばらくはReactの記事を書いていきたいと思います! 今回は、Reactでi18n対応する方法について紹介します。

react-intlとは?

ReactやVue.jsなどで、i18n対応ができるパッケージです。総称してFormat.jsと呼ばれていますが、実際に使用するパッケージは react-intl になります。GithubのStart数も多く、人気のパッケージです。
https://formatjs.io/

react-intlの導入

まずは、create-react-appします。

次に、Format.jsを追加します。また、今回はCSSフレームワークとしてMUIを使用するので、併せて追加します。

使い方

IntlProviderの実装

react-intlは、Reactコンテキストとして実装されており、i18n対応したい箇所を <IntlProvider> コンポーネントで囲う必要があります。IntlProviderは、ロケールや翻訳メッセージなどを持ち、配下の <Formatted*> コンポーネントで使用されます。
一般的には、Reactコンポーネントのルートに近い位置に <IntlProvider> コンポーネントを置き、アプリケーション全体で使えるようにした方が良いそうなので、そのように実装してみます。

index.tsxを編集します。

IntlProviderに渡しているPropsについて説明します。

  • locale
    ja、enなどのロケールが入ります。今回は、 navigator.language から取得しているため、ブラウザの言語設定が入ります。後ほど説明する日時フォーマットは、ここのlocaleによって適切にフォーマットされます。
  • messages
    翻訳メッセージを渡します。今回は selectMessages() で、 navigator.language によってメッセージを切り替えています。メッセージ自体は、JSONファイルに定義して、importしています。

メッセージ定義

今回は、JSONファイルにメッセージを定義していきます。構造はフラットにする必要があるため、構造を示す場合には . などで区切ります。

src/lang/en.json

src/lang/ja.json

<Foramatted*>コンポーネントの使用

IntlProviderの配下で、実際にi18nしていくには、 <Formatted*> コンポーネントを使います。

メッセージ

先ほど定義したメッセージを表示させるには、 <FormattedMessage> を使用します。

「こんにちは、太郎さん!」と表示されました。
この他にも、様々なMessage Syntaxに対応しているので、よく使いそうなものを紹介します。

複数形対応

複数形を表現するには、 plural フォーマットを使用します。

翻訳メッセージ内に {key, plural, matches} という形式で表します。

  • key
    複数化を判断するための数値を受け取ります。
  • plural
    複数形フォーマットを指定するため、 plural を指定します。
  • mathces
    keyの値によって表示させたいメッセージを指定します。書式は 条件 {文言} です。条件には、次のようなものがあります。

    • one: 単数
    • other: 複数
    • =value: 特定の数値

英語や日本語以外では、上記以外の条件を使うこともあるようです。詳しくはこちらの公式リファレンスが参考になります。
https://formatjs.io/docs/core-concepts/icu-syntax/#plural-format

日時

まず、日付を表示させてみます。

これで、「2021年11月30日(火)」と表示されました。プロパティを渡さなくすれば、表示させないようにすることもできます。
また、 year , weekday , month , day などのプロパティを全て渡さなければ、デフォルトである「2021/12/1」と表示されるようになります。

次に、時間を表示させてみます。

こちらは、「19:21:54」と表示されました。もし秒数が不要であれば、 second= を削除すれば表示されなくなります。(その場合、デフォルト設定と同じになるため、hour, minute, secondを全て削除しても構いません。)

<FormattedDate><FormattedTime> は、使用箇所でいちいち定義するより、いずれもラップしたコンポーネントを作り、アプリケーション全体で共通化した方が良いと思いました。日時のフォーマットは、アプリケーション全体で統一感を持たせた方が良いと思うためです。

タイムゾーンについて

<FormattedDate><FormattedTime> は、valueに渡されたDateオブジェクトをもとにフォーマットを行います。そのため、ISO8606形式の日付を Date.parse() でパースすれば、ブラウザのタイムゾーンに変換して表示させることができます。

UTC時間で0時を指定していますが、ブラウザで表示してみると「2021年1月1日(金) 9:00:00」と表示され、ブラウザのタイムゾーンに変換されていることが分かります。

ちなみに、Chromeでタイムゾーンを変更するには、Developer Toolsを開き、「…」からSensorsを開きます。Locationを変更してからリロードすると、タイムゾーンによって時刻の表示が変わることが確認できます。

数値(通貨など)

数値のフォーマットを行うには、 <FormattedNumber> を使います。
まず、通貨の表示をやってみます。

USDは「$ 10.00」、JPYは「\ 1,000」と表示されました。このように、通貨に合わせてフォーマットされます。

その他にも、 style="unit" とすることで、様々な単位の数値を出力するこどがてきます。

たとえば、上記の場合は「10 MB」と表示されます。その他にも様々な単位が用意されています。詳しくは下記のを参照してください。
https://formatjs.io/docs/polyfills/intl-numberformat#SupportedUnits

命令型APIの呼び出し

ここまでに紹介した、 Formatted** は Reactコンポーネントとして描画するほかに、命令型APIとしても同じ機能が用意されています。 useIntl フックが用意されているので、これを使います。

例えば、MUIのSnackbarでは、表示するメッセージをstringで渡す必要があります。そこで、 intl.formatMessage() を使うと、 <FormattedMessage> と同じ結果を得られます。
基本的には、 format** という関数名で、先ほど紹介したReactコンポーネントと同じ結果を得ることができます。

言語の変更

ここまでのサンプルでは、 navigator.language でブラウザの言語を取得していましたが、今度は言語をアプリケーション内で変更できるようにしたいと思います。
今回は、 IntlProvider をラップしたReact コンテキストを実装することで、localeやmessagesを切り替えできるようにしたいと思います。

まずは、React コンテキストから実装していきます。

まず、 const langs に言語を定義していきます。ここで定義したプロパティは、そのまま IntlProvider に渡すため、 IntlProvider のプロパティのインターフェイスに合わせておきます。
また、 switchLang 関数を公開することで、子コンポーネントから言語を切り替えることができるようになっています。 switchLang 関数では、指定されたlocaleを探し、 setLang しています。
そして、 <IntlProvider {...lang}> とすることで、選択された言語情報を渡し、変更があったときに再描画されるようにしています。

最後に、index.tsxを修正します。

先ほど作成した <IntlProviderWrapper> で、 <App /> を囲います。これで、アプリケーション全体で、どこからでも言語を変更できるようになりました。
それでは、さっそく言語を変更してみましょう。

先ほど公開した switchLang 関数を呼び出し、言語を変更することができました。

さいごに

react-intlを使うと、i18nだけでなく、日時や単位のフォーマットもできることが分かりました。

おすすめ書籍

Reactハンズオンラーニング 第2版 ―Webアプリケーション開発のベストプラクティス プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発

blog-page_footer_336




blog-page_footer_336




-FrontEnd
-

執筆者:


comment

メールアドレスが公開されることはありません。

CAPTCHA


関連記事

tailwindcss

Tailwind CSSの基礎とVue.jsへの導入

1 はじめに2 Tailwind CSSとは2.1 utility class3 Bootstrapとの比較3.1 柔軟性3.2 コード量3.3 学習コスト3.4 ファイルサイズ3.5 その他4 なぜ ...

Vue CLIでPWAが簡単に実装できる 〜 Service Worker と A2HS 〜

1 はじめに2 環境構築2.1 Vue CLIをインストール2.2 プロジェクトを作成2.3 PWA選択時に追加されるファイル2.4 動作確認時の注意3 Service Worker3.1 Servi ...

Cordovaの実機デバッグでハマった話

1 はじめに2 Cordovaとは2.1 React Nativeとの違い3 Cordovaでモバイルアプリを作る3.1 Node.jsをインストール3.2 Cordovaのコマンドラインツールをイン ...

Vue.js入門その1〜基本文法〜

はじめに 軽量JSフレームワークとして有名なVue.js。 最近、Laravelに触れる機会が増えたことと、以前からRails + Vueという構築を耳にするので、今更ではありますが勉強を始めようと思 ...

[Rails + Materialize] DateTimePickerがなかったので…

1 はじめに2 前提条件2.1 ビューのイメージ3 モデルにゲッターとセッターを追加4 入力フォームに追加4.1 JSファイルにて使用宣言4.2 HTML4.3 コントローラーのストロングパラメータを ...

フォロー

blog-page_side_responsive

2021年12月
 1234
567891011
12131415161718
19202122232425
262728293031  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。