iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
0
Modern Web

React 30天系列 第 25

Day 25-你好,Hello,こんにちは(react-intl初認識)

  • 分享至 

  • xImage
  •  

i18n,也就是internationalization,我們可以透過它管理多國語言切換,而react-intl則是FormatJS的一部分。FormatJS是用於i18n的JavaScript library的modual集合,並著重於向使用者顯示的格式化數字、日期和字串。

當初想切入i18n時剛好受到這則影片的啟發,讓我內心湧起:"欸油~好像不錯!"的念頭,所以就讓我們一起看看react-intl是怎麼實現多國語系切換的吧!
Yes

首先,先來看看他有什麼特徵吧!

  1. 用分隔符顯示數字,如:1000.95
    • 英語 1,000.95
    • 法語 1 000,95
  2. 正確顯示日期和時間,如:new Date()
    • 英語(美語) 11/1/2018
    • 法語 1/11/2018
  3. 顯示與"現在"相對的日期,如:"2018-10-2"
    • last month
    • 1 month ago
    • 30 days ago
  4. 幫忙把string變複數(英文有需要,中文沒影響),如:
    • one: "message"
    • other: "messages"
  5. 支援150種以上的語言
  6. 可以運行在browser和 Node.js
  7. 建立在標準之上

這次先不急著實作,先一起來看看react intl有哪些module可以使用!
The React Intl Module

  • addLocaleData - 這個function提供了一種方式向library註冊locale data,它支援複數(comment & comments)和相對時間(1分鐘前,1週前...等等)格式化功能,而react intl也提供了UMD Locale Data各種locales供大家使用。另外,其中的index.js涵括所有locales,實際用法如下:
    import {addLocaleData} from 'react-intl';
    import frLocaleData from 'react-intl/locale-data/fr';
    
    addLocaleData(frLocaleData);
    
  • intlShape - 這個function提供了object的React prop validator,可以用來與injectIntl一起使用。實際連過去後發現沒有相關內容,但該跟PropTypes有關。
  • injectIntl - injectIntl是一個High-Order Component (HOC),就像我們之前在react-redux用到的connect類似,透過props.intl注入formatting API以供component使用。一般來說我們會使用到的格式化訊息大多使用React Intl Components產出react element,但有些使用情境需要的是改變element的attribute(比如說title、aria或是用於componentDidMount的side-effect。
  • IntlProvider - <IntlProvider>用來設定i18n context,通常會把整個root component包起來。其中props的設定常見的有:
    1. locale: 當前的語言環境,value為string,如:"en"或"zh",其他選項可參考locale data
    2. key: 動態語言選擇,一般來說在運行application時不會因為設定的locale改變而重新渲染,所以需要透過key值更動和react説component已經修改了。
    3. messages: object,內容格式為{[id: string]: string},自己需設定的訊息,之後顯示的各語系訊息就是從messages取得。
    <IntlProvider locale={localeProp} key={localeProp} messages={messagesProp}>
      <App />
    </IntlProvider>
    

Date Formatting Components(日期格式化組件)

  • FormattedDate - 這個component使用formatDateIntl.DateTimeFormat API,相關options設定可參考DateTimeFormatOptions,預設產出的element為span,如果想用其他的element(比如說div),就用<div>把<FormattedDate>包起來就好ಠ_ರೃ,要不然就是送個function做為child。FormattedDate使用範例和結果如下:
    <FormattedDate value={new Date(1459832991883)}/>
    <span>4/5/2016</span>
    
    有options的範例:
    <FormattedDate
      value={new Date(1459832991883)}
      year='numeric'
      month='long'
      day='2-digit'
    />
    <span>April 05, 2016</span>
    
  • FormattedTime - 這個component使用formatTime和Intl.DateTimeFormat API,其他同上面的FormattedDate。FormattedTime使用範例和結果如下:
    <FormattedTime value={new Date(1459832991883)}/>
    <span>1:09 AM</span>
    
  • FormattedRelative - 這個component使用formatRelative API,它也有相關的options可參考RelativeFormatOptions

Number Formatting Components(數字格式化組件)

  • FormattedNumber - 使用formatnumberIntl.NumberFormat API,也是可以設定options,options可參考NumberFormatOptions,其也都跟樓上一樣預設是span,使用範例和結果如下:
    <FormattedNumber value={1000}/>
    <span>1,000</span>
    

對不起已經被我的重複碎念感到厭煩的各位,基本上就是用不同的api,加上不同的options,產出不同的內容,但都會是<span>,之後我們快速用範例帶過吧!

  • FormattedPlural - 使用formatPlural API
    <FormattedPlural
      value={10}
      one='message'
      other='messages'
    />
    <span>messages</span>
    

String Formatting Components(字串格式化組件)

  • FormattedMessage - 使用formatmessage API,相關的props設定可參考Message Descriptor
    <FormattedMessage
      id='app.greeting'
      description='Greeting to welcome the user to the app'
      defaultMessage='Hello, {name}!'
      values={{
        name: 'Eric'
      }}
    />
    <span>Hello, Eric!</span>
    
    <FormattedMessage id="title">
      {(txt) => (
        <H1>
          {txt}
        </H1>
      )}
    </FormattedMessage>
    <h1>Hello, Eric!</h1>
    
  • FormattedHTMLMessage - 不推薦,可以用FormattedMessage處理就用FormattedMessage就好。先記著,之後有需要再來查。

今日總結:
大概有了概念後,明天我們就來實作吧!
看起來主要會影響的範疇就在時間、數字和訊息做語系替換,稍微了解之後,其實i18n也是蠻親民的呢~
希望明天順利!


上一篇
Day 24-透過URL Parameters處理News內頁
下一篇
Day 26-讓todos變得國際化吧
系列文
React 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言