簡介
如果一個應用程式在設計時,可以在不修改應用程式的情況下,根據不同的使用者直接採用不同的語言、數字格式、日期格式等,這樣的設計考量稱為國際化(internationalization),簡稱i18n(因為internationalization有18個字母)。
國際化的重要觀念之一是地區(Locale)資訊,地區資訊代表了特定的地理、政治或文化區,地區資訊可由一個**語言編碥(Language code)與可選的區域編碼(Country code)**來指定,其中語言編碼是 ISO-639 定義,由兩個小寫字母代表,例如”ca”表示嘉泰羅尼亞文(Catalan),”zh”表示中文(Chinese)。
區域編碼則由兩個大寫字母表示,定義 在ISO-3166, 例如IT表示義大利(Italy)、TW表示台灣(Taiwan)。
在React中的用法
安裝 react-intl
yarn add react-intl
使用 IntlProvider
將 <IntlProvider> 包在最外層,讓所有內部 component 都可以存取到它提供的屬性與方法。
取得使用者語系並帶入 IntlProvider
接著:
- 透過 navigator.language 取得使用者在瀏覽器上所使用的語系,並且將它代入 IntlProvider 的 local 屬性中
- 若有需要可以定義 defaultLocale 屬性
定義多語系字典檔
做好上述設定後,就可以來定義多語系用的字典檔。假設我們要做 i18n 的內容是範例頁面中的「Learn React」這個部分:
這時候就可以先定義這個字典檔。首先在 ./src 資料夾內再新增一個 i18n 的資料夾,裡面分別放入 en.js, zh.js, ja.js:
接著分別定義每支字典檔的內容,這裡的 app.learn 可以視為 id,之後的使用 react-intl 提供的方法或組件時,他會根據你提供的這個 id 來帶入不同的內容,而 { } 刮起來的 name 表示它是動態的變數:
**// ./src/i18n/en.js**
const en = { 'app.learn': 'Learn {name}' };
export default en;
**// ./src/i18n/zh.js**
const zh_TW = { 'app.learn': '學習 {name}' };
export default zh_TW;
**// ./src/i18n/ja.js**
const ja_JP = { 'app.learn': '学び {name}' };
export default ja_JP;
撰寫切換語言的功能
因為一開始使用的是 functional component,想要添加狀態(state)的話,可以匯入 useState
在 App.js 的地方,撰寫三個按鈕可以來切換 locale 的狀態:
文字訊息多語系
這裡說明的是最一般用來轉換不同語系字串的作法,react-intl 提供了:
根據不同的語言傳入不同的語系檔
可以切換 locale 的狀態後,最後就可以根據使用者選擇的語言傳入不同的語系檔。
先將剛剛撰寫好的語系檔載入:
接著定義 messages 這個變數,透過 if 判斷使用者切換到的語言為何,最後將 messages 傳入 <IntlProvider>:
在組件中使用語系檔
在 index.js 中,使用者在切換語言後,我們會提供不同的語系檔到 <IntlProvider> 的 messages 屬性內。現在,在 App.js 中就可以使用 react-intl 提供的 <FormattedMessage> 方法來顯示。
在 <FormattedMessage /> 中,id 會對應到先前寫在 ./src/i18n/ 資料夾內的語系檔中定義的屬性 app.learn,而 values 是因為在語系檔中有定義
可以再使用 intl.formatMessage的方式,做一個歡迎使用者的文字:
要使用 intl.formatMessage ,要先引入 react-intl 的 hook :
這時候就完成了簡單的 i18n 語系替換:
時間日期多語系
在 react-intl 中也提供了時間、日期的多語系功能,包含:
完成的結果如下:
如果有需要也可以使用 <FormattedRelativeTime>,這個方法會回傳距今的時間:
顯示的結果如下:
數值多語系
若有需要針對數值進行多語系的切換,react-intl 則提供了:
- <FormattedNumber>
其他Component
react-intl 還有很多不同的 Component 可以針對不同語言、語系做變化: