react 国际化_React的国际化
react 國際化
by Preethi Kasireddy
通過Preethi Kasireddy
React的國際化 (Internationalization in React)
Internationalization is a big problem. If you want your application to make a worldwide impact, you have to deal with language barriers.
國際化是一個大問題。 如果您希望您的應用程序對全球產生影響,則必須應對語言障礙。
Unfortunately, the road from “Your funds will arrive by July 7th” to “Vos fonds arriveront le 7 Juillet” is far from simple.
不幸的是,從“您的資金將在7月7日到達”到“ Vos fonds抵達7 Juillet”的路途并非一帆風順。
Before your application can succeed outside the English-speaking world, you’ll have to adapt all your strings, dates, and numbers to the conventions of different cultures.
在您的應用程序在英語國家以外的地區獲得成功之前,您必須使所有字符串,日期和數字適應不同文化的慣例。
Developers call this practice internationalization (which is often abbreviated to “i18n,” because there are 18 letters between the ‘I’ and the ’n’ in the word Internationalization.)
開發商稱這種做法國際 (通常縮寫為“ 國際化 ”,因為有“ 我 ”和“ 否 ”字我 nternationalizatio N的18個字母。)
One reason we overlook internationalization is simply because it’s hard to get right. Every language has different rules and conventions. Adapting to these rules and conventions takes time and effort.
我們忽略國際化的原因之一僅僅是因為很難做到正確。 每種語言都有不同的規則和約定。 適應這些規則和約定需要花費時間和精力。
解決方案:React Intl (The solution: React Intl)
But internationalization doesn’t have to be hard, thanks to a new React library. React Intl is an open-source project from Yahoo, and part of Format.js, a collection of JavaScript libraries for internationalization that builds on Javascript’s built-in Intl API.
但是,由于有了新的React庫,國際化并不難。 React Intl是Yahoo的一個開源項目,它是Format.js的一部分, Format.js是基于Javascript的內置Intl API構建的國際化JavaScript庫的集合。
The React Intl library makes internalization in React straightforward, with off-the-shelf components and an API that can handle everything from formatting strings, dates, and numbers, to pluralization.
React Intl庫提供了現成的組件和一個API,可以處理React中的內部化,該API可以處理從格式化字符串,日期和數字到復數的所有內容。
Let’s give it a walk-through.
讓我們來看一下。
核心概念 (Core concepts)
Here are the core concepts you’ll need under your belt to get the most out of React Intl:
要充分利用React Intl,您需要掌握以下核心概念:
JavaScript的國際化API (JavaScript’s Internationalization API)
JavaScript has an Internationalization API specification which defines the Intl object as a standard built-in global object.
JavaScript具有國際化API規范,該規范將Intl對象定義為標準的內置全局對象。
React Intl essentially uses and builds on this API. As long as the browser supports these APIs, React Intl will continue to work its magic.
React Intl本質上使用并以此API為基礎。 只要瀏覽器支持這些API,React Intl就會繼續發揮其魔力。
Note: the only browser that doesn’t currently support these APIs is Safari. We’ll use a polyfill to overcome this in the sample project below.
注意:Safari當前是唯一不支持這些API的瀏覽器。 在下面的示例項目中,我們將使用polyfill來克服這一問題。
模塊捆綁器 (Module bundlers)
React Intl distributes its package via ES6, CommonJS, and UMD modules. Hence, it works really well with bundlers like Webpack, Browserify and Rollup.
React Intl通過ES6,CommonJS和UMD模塊分發其軟件包。 因此,它與Webpack,Browserify和Rollup等捆綁程序一起使用時效果很好。
In the sample project, we’ll be using Webpack as our module bundler.
在示例項目中,我們將使用Webpack作為模塊捆綁器。
If you don’t plan to use a module bundler to load React Intl into your application, I recommend the documentation for more information on other approaches (e.g. via Node.js).
如果您不打算使用模塊捆綁程序將React Intl加載到您的應用程序中,那么我建議您使用該文檔以獲取有關其他方法的更多信息(例如,通過Node.js)。
加載區域設置數據 (Loading Locale data)
React Intl relies on this locale data to support plural and relative-time formatting. Locale data defines the following for each specific locale:
React Intl依賴于此語言環境數據來支持復數和相對時間格式。 語言環境數據為每個特定語言環境定義了以下內容:
- Locale-specific patterns for formatting and parsing dates, times, time zones, numbers and currency values 特定于語言環境的模式,用于格式化和解析日期,時間,時區,數字和貨幣值
- Translations for names of currencies, eras, months, weekdays, etc. 貨幣名稱,時代,月份,工作日等的翻譯。
- Language and script information (plural cases, characters used, gender of lists, capitalization, writing direction, etc.) 語言和文字信息(多種情況,使用的字符,列表的性別,大小寫,書寫方向等)
- Country information (currency, calendar preference, week conventions, telephone codes, etc.) 國家信息(貨幣,日歷首選項,星期慣例,電話代碼等)
If you’re using Browserify, Webpack or Rollup to bundle React Intl for the browser, it will only contain locale data for basic English by default. The rest of the locale data is not included in the main library. So in this sample project we’ll cover how to import the locale data per language you choose to support in your app.
如果您使用Browserify,Webpack或Rollup為瀏覽器捆綁React Intl,則默認情況下,它將僅包含基本英語的語言環境數據。 其余的語言環境數據不包含在主庫中。 因此,在此示例項目中,我們將介紹如何在您選擇的應用程序中支持的每種語言下導入語言環境數據。
Keep in mind that if you’re using React Intl via Node.js, all locale data will be loaded into memory, so you can skip this step.
請記住,如果您通過Node.js使用React Intl,則所有語言環境數據都會加載到內存中,因此您可以跳過此步驟。
使用React Components與API格式化數據 (Formatting Data using React Components vs. the API)
The library provides two ways to format strings, numbers, and dates: React components or an API.
該庫提供了兩種格式化字符串,數字和日期的格式: React 組件或API 。
React Component:
React組件:
API:
API:
I take the first approach whenever possible, using declarative idiomatic-React components to format data over the imperative API.
我會盡可能采用第一種方法,即使用聲明性的慣用React組件通過命令式API格式化數據。
The benefit of this approach is that it lets us a) compose components with other components, b) allows for rich text and string formatting, c) provides prop type warnings for formatting options, and d) implements shouldComponentUpdate to avoid costly formatting operations.
這種方法的好處是,它使我們可以:a)與其他組件組成組件,b)允許使用富文本格式和字符串格式,c)為格式選項提供屬性類型警告,d)實現shouldComponentUpdate以避免昂貴的格式化操作。
Of course, there are times when your only choice is to use the API (For example: passing a string as a prop, a name attribute of an HTML element, etc.), so it still comes in handy.
當然,有時候您唯一的選擇就是使用API??(例如:將字符串作為道具傳遞,HTML元素的name屬性等),因此它仍然派上用場。
樣例項目 (Sample project)
The best way to learn is to see a live example. For this post, I made a simple React project which consists of a main header component, a subheader component, and a few widget components, each with their own headers and body.
最好的學習方法是看一個生動的例子。 在本文中,我制作了一個簡單的React項目 ,該項目由一個主要的標頭組件,一個子標頭組件和一些小部件組成,每個都有自己的標頭和正文。
First, we’ll walk through the process of setting up React Intl. Then we’ll use the components and API to convert strings, numbers, and dates used within the components.
首先,我們將逐步完成設置React Intl的過程。 然后,我們將使用組件和API來轉換組件中使用的字符串,數字和日期。
配置 (Setting up)
Let’s assume we have an existing React application that we’re working from. First, you’ll need to install the React Intl package:
假設我們有一個正在使用的現有React應用程序。 首先,您需要安裝React Intl軟件包:
Next, we’ll need to install the babel plugin for React Intl:
接下來,我們需要為React Intl安裝babel插件:
To actually have the babel plugin do its magic, we need to set up our .babelrc file to include this plugin. Here’s what my .babelrc looks like with the react-intl plugin added to it (lines 6–11):
為了使babel插件真正發揮作用,我們需要設置.babelrc文件以包含此插件。 這是添加了react-intl插件后的.babelrc的樣子(第6-11行):
What this babel plugin does is it extract all the string messages in your application that are defined using either defineMessages, <FormattedMessage>;, or <FormattedHTMLMessage>.
這個babel插件的作用是提取應用程序中所有使用defineMessages , <FormattedMessa ge> ;或<FormattedHTM LMessage>定義的字符串消息。
(Note that defineMessages, <FormattedMessage>, and <FormattedHTMLMessage> are all named exports of the React Intl package).
(請注意, defineMessages , <FormattedMessa ge> 和<FormattedHTM LMessage>都是React Intl包的命名導出)。
Once extracted, it generates JSON files which contain the string messages and places them in the directory you defined in the messagesDir path above.
提取后,它將生成包含字符串消息的JSON文件,并將其放置在您在上面messagesDir路徑中定義的目錄中。
加載數據中 (Loading data)
Next, let’s load the appropriate locale data for the languages that we need to support.
接下來,讓我們為需要支持的語言加載適當的語言環境數據。
As I mentioned above, if you’re bundling for the browser using Webpack, Browserify or Rollup, React Intl comes English-only by default. So we have to add the other locale data manually.
如前所述,如果您使用Webpack,Browserify或Rollup捆綁瀏覽器,則默認情況下React Intl僅提供英語。 因此,我們必須手動添加其他語言環境數據。
In the root component file, we add the locale data using the addLocaleData API. The data will then be passed the contents of the locale data module, which will then be registered in its locale data registry.
在根組件文件中,我們使用addLocaleData API添加語言環境數據。 然后將數據傳遞給區域數據模塊的內容,然后將其注冊在其區域數據注冊表中。
For this sample project, I’m going to assume we’re supporting 4 languages: English, Spanish, French and Italian.
對于此示例項目,我將假設我們支持4種語言:英語,西班牙語,法語和意大利語。
Note: If your app supports a lot more, the recommended approach to adding locale data is to dynamically load the locale data based on the current user’s language. Read the React Intl docs for more info on this approach.
注意 :如果您的應用程序支持更多,則推薦的添加區域設置數據的方法是根據當前用戶的語言動態加載區域設置數據。 請閱讀React Intl文檔以獲取有關此方法的更多信息。
在您的React應用程序中創建i18n上下文 (Create the i18n context in your React application)
So far, we’ve installed the React Intl package, set up our .babelrc plugin, and loaded the appropriate locale data.
到目前為止,我們已經安裝了React Intl軟件包,設置了.babelrc插件,并加載了適當的語言環境數據。
One final step is to create an i18n context for all our React components so that the current user’s locale and translated message (based on the user’s locale) can be loaded into the React Intl Components that you define in your app.
最后一步是為我們所有的React組件創建一個i18n上下文,以便可以將當前用戶的語言環境和翻譯后的消息(基于用戶的語言環境)加載到您在應用中定義的React Intl組件中。
To do this, we first define the messages to pass to IntlProvider based on the user’s locale (see lines 18–26 below). Then we wrap the root React component with IntlProvider, which is a named export provided by React-Intl (see lines 31–33):
為此,我們首先根據用戶的區域設置定義要傳遞給IntlProvider的消息(請參見下面的第18-26行)。 然后,使用IntlProvider包裝根React組件,該組件是 由React-Intl提供的命名導出(請參閱第31-33行):
In this setup, we’re assuming that our translated data will live in build/locales/data.json and that the data is grouped by language, like so:
在此設置中,我們假設翻譯后的數據將位于build / locales / data.json中 ,并且該數據按語言分組,如下所示:
構建腳本進行翻譯 (Build a script for translating)
Now that we have the configuration all done, let’s take a look at how we can build a simple script that will grab all the strings that babel extracts for us into multiple JSON files, and combine them into one file.
現在我們已經完成了配置,讓我們看一下如何構建一個簡單的腳本,該腳本將babel為我們提取的所有字符串捕獲到多個JSON文件中,并將它們組合為一個文件。
The point of this script is to accumulate all the English strings so that we can then upload these strings to a translation service, have them be translated into the different languages we support, and then place the results into the build/locales/data.json file we used above. Once there, the IntlProvider component can finally load them into our root component.
該腳本的重點是累積所有英語字符串,以便我們可以隨后將這些字符串上載到翻譯服務,將它們翻譯成我們支持的其他語言,然后將結果放入build / locales / data.json中。我們上面使用的文件。 到達那里之后, IntlProvider組件最終可以將它們加載到我們的根組件中。
Since we don’t need to actually do the translations in this post, we’ll skip this step and just build a script that puts everything in one file. Just remember to loop in a translation service provider in real-world applications :)
由于我們實際上不需要翻譯本文,因此我們將跳過此步驟,只構建一個將所有內容放入一個文件的腳本。 只需記住在實際應用中循環使用翻譯服務提供商即可:)
All credit goes to the React Intl library authors for generating this script below:
所有功勞歸功于React Intl庫作者在下面生成此腳本的方式:
使用React Intl轉換日期,數字和字符串的步驟 (Steps to convert dates, numbers and strings with React Intl)
Okay — we’re finally ready to do some formatting!
好的-我們終于可以進行格式化了!
The sample app is a simple layout with a header, subheader, and widgets, each of which contains strings, numbers, and/or a dates:
示例應用程序是一個簡單的布局,其中包含header , subheader和小部件 ,每個小部件都包含字符串,數字和/或日期:
Nothing sophisticated, but it’s enough to get us started.
沒什么復雜的,但是足以讓我們開始。
標頭 (Header)
First, we’ll look at the header which says: “Welcome to your dashboard, Preethi!”
首先,我們看一下標題為: “歡迎使用儀表板,Preethi!”
To convert this, we’ll use the FormattedMessage component:
要進行轉換,我們將使用FormattedMessage組件:
The FormattedMessage component has props that correspond something called a “Message Descriptor” in React Intl. The Message Descriptor is the format used to define default messages/strings, and is useful for providing the data necessary for having the strings/messages translated. It contains the following properties:
FormattedMessage組件具有對應于React Intl中稱為“ Message Descriptor ”的道具。 消息描述符是用于定義默認消息/字符串的格式,對于提供轉換字符串/消息所需的數據很有用。 它包含以下屬性:
id: A unique, stable identifier for the message
id :消息的唯一,穩定的標識符
description: Context for the translator about how it’s used in the UI (optional)
description :翻譯器在UI中的使用方式上下文(可選)
defaultMessage: The default message (in English)
defaultMessage :默認消息(英文)
The id prop must be unique for every message defined in your app. What’s awesome is that the defaultMessage can be passed data from the props, as is the case in name above. (Note that the values that are passed as data won’t get translated — they’re simply inserted into the final translated string as-is.)
ID道具對于您應用中定義的每條消息都必須是唯一的。 很棒的是,可以從props傳遞數據到defaultMessage ,就像上面的名字一樣 。 (請注意,作為數據傳遞的值將不會被翻譯,它們只是按原樣插入最終的翻譯字符串中。)
副標題 (SubHeader)
Next, let’s look at the Subheader, which is slightly more involved:
接下來,讓我們看一下Subheader,它稍微復雜一些:
The ability to compose components within other components (i.e. have Formatted* items within another Formatted* item) is a powerful feature of React Intl.
其他組件中撰寫組件的能力(即已經格式化另一個格式化 *項中*項目)是發生React國際強大的功能。
You can see in the above example that unreadCount is a FormattedNumber, and notifications is a FormattedPlural, and that both are values passed into FormattedMessages’s defaultMessage. Beautiful!
在上面的示例中,您可以看到unreadCount是FormattedNumber , 通知是FormattedPlural ,并且兩者都是傳遞到FormattedMessages的defaultMessage中的值。 美麗!
Another slick feature is FormattedRelative, which will render the formatted relative time:
另一個巧妙的功能是FormattedRelative ,它將呈現格式化的相對時間:
Once translated and formatted, it will read: “You last logged in 4 hours ago!” (Or however long ago lastLogin was.)
翻譯和格式化后,它將顯示為: “您上次登錄是4小時前!” (或者很久以前,lastLogin是。)
傳遞格式化的字符串作為組件 (Passing formatted strings as components)
In the above two snippets, we saw how to use the Formatted* Components to define strings, numbers, dates, and pluralization.
在以上兩個片段中,我們了解了如何使用Formatted * Components定義字符串,數字,日期和復數形式。
However, there are plenty of instances where it’s necessary to pass formatted strings as props or use formatted strings to name an HTML component. The FormattedMessage component doesn’t well work in cases like this.
但是,在很多情況下,有必要將格式字符串作為prop傳遞或使用格式字符串命名HTML組件。 在這種情況下, FormattedMessage組件不能很好地工作。
Luckily, React Intl’s defineMessages API lets us imperatively define all of a component’s strings, then pass them as props to the component.
幸運的是,React Intl的defineMessages API使我們能夠命令性地定義組件的所有字符串,然后將它們作為prop傳遞給組件。
Let’s try this approach for the widget headers and body. First, we use defineMessages to define our strings:
讓我們為小部件標題和正文嘗試這種方法。 首先,我們使用defineMessages定義字符串:
Then, assuming we have a Widget component that expects header and body props, we can continue like so:
然后,假設我們有一個需要標題和正文道具的Widget組件,我們可以像這樣繼續:
One thing you might have noticed in the first widget is that we can also pass data to the strings defined in defineMessages. Here, we passed the current formatted date as the value date. Pretty neat, huh?
您可能在第一個小部件中注意到的一件事是,我們還可以將數據傳遞到defineMessages中定義的字符串。 在這里,我們將當前的格式化日期作為值date傳遞。 很整潔吧?
The API also works well for formatting numbers, dates, times, relative times, and pluralization (check out their docs for more on this)
該API還可以很好地用于格式化數字,日期,時間,相對時間和復數形式(有關更多信息,請查看其文檔 )
如何使其在Safari中工作 (How to make it work in Safari)
Now that we’re almost done, I’ll throw one last curve ball at you:
現在我們快完成了,我將向您扔最后一個曲線球:
The current setup will not work for Safari browsers :(
當前設置不適用于Safari瀏覽器:(
As mentioned above, this is because Safari does not currently have native support for Javascript’s Internationalization API.
如上所述,這是因為Safari當前不支持Javascript的Internationalization API。
Fortunately, there’s still a way to make this work for Safari users. What we need to do is use the Intl polyfill. There are a few different ways to load this in. Let’s continue using Webpack, for the sake of example:
幸運的是,仍然有一種方法可以使Safari用戶正常工作。 我們需要做的是使用Intl polyfill 。 有幾種不同的加載方法。為了舉例,讓我們繼續使用Webpack:
First, we install the intl package from npm:
首先,我們從npm安裝intl軟件包:
Next, we’ll write a simple if-statement to only load the polyfill if there is no native browser support for Intl (see lines 30–57). This is to avoid loading the library and all the locale data into your app when not needed.
接下來,我們將編寫一個簡單的if語句,僅在不支持Intl的本機瀏覽器時才加載polyfill(請參閱第30-57行)。 這是為了避免在不需要時將庫和所有語言環境數據加載到您的應用程序中。
As you can see, the first thing to check is if the intl global is not available on window. If not, then we load the intl polyfill and associated locale data and then render the component. Otherwise, we simply render the component.
如您所見,首先要檢查的是intl全局窗口是否不可用。 如果不是,則加載intl polyfill和關聯的語言環境數據,然后渲染組件。 否則,我們僅渲染組件。
And at last, here’s our pre-translated app (still in English of course). I’ll leave you with the final step, which is finding a translation provider and getting these strings translated!
最后,這是我們的預翻譯應用程序(當然仍然是英語)。 我將為您提供最后一步,這是找到翻譯提供商并翻譯這些字符串!
其他提示 (Other tips)
I hope this post is enough to start turning your spazzy React application into one that’s amicable to other cultures and languages.
我希望這篇文章足以使您出色的React應用程序變成適合其他文化和語言的應用程序。
Before I sign off, here are a few other tips to consider when internationalizing your app:
在我退出之前,這里是一些國際化您的應用程序時要考慮的其他提示:
Flexible components: Build your components such that they are flexible and allow for text expansion and shrinkage. Some languages can expand much larger or shrink much smaller than English. If you don’t account for this, your layout can look unbearable after translation.
靈活的組件:構建組件時應使其靈活,并允許文本擴展和縮小。 有些語言可以比英語大得多或小很多。 如果您不考慮這一點,那么在翻譯后您的布局可能看起來難以忍受。
Appropriate font size: Use a font size that will work well with all the languages you support. Some languages, like Japanese and Chinese, need larger font sizes.
適當的字體大小:使用適合您支持的所有語言的字體大小。 某些語言(例如日語和中文)需要更大的字體。
UTF-8: Use UTF-8 everywhere. This includes in your HTML, server-side language, database, etc. Unlike other encodings, UTF-8 encoding handles almost all languages really well.
UTF-8 :到處都使用UTF-8。 這包括HTML,服務器端語言,數據庫等。與其他編碼不同,UTF-8編碼幾乎可以很好地處理所有語言。
No text in images: Avoid using text in images because translating text in graphics is extremely difficult, and not worth the pain.
圖像中沒有文本:避免在圖像中使用文本,因為在圖形中翻譯文本非常困難,也不值得付出痛苦。
Don’t split your strings: For example, if you have “Your funds will arrive by July 7th,” avoid splitting strings like “Your funds will arrive by” and “July 7th”. The combination might only work in English due to word order variations in other languages.
不要分割字符串:例如,如果您有“您的資金將在7月7日到達”的信息,請避免分割字符串,例如“您的資金將在7月7日到達”和“ 7月7日”。 由于其他語言的字序變化,該組合可能僅適用于英語。
結論 (Conclusion)
As always, feel free to comment with suggestions and questions. I’d love to hear it :)
與往常一樣,請隨時提出建議和問題。 我很想聽聽:)
All the code for the sample application can be found on github here: https://github.com/iam-peekay/inbox-react-intl
該示例應用程序的所有代碼都可以在github上找到: https : //github.com/iam-peekay/inbox-react-intl
翻譯自: https://www.freecodecamp.org/news/internationalization-in-react-7264738274a0/
react 國際化
總結
以上是生活随笔為你收集整理的react 国际化_React的国际化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机军中绿花谱子,军中绿花电子琴曲谱
- 下一篇: 有人已经查到考研成绩了!真的吗?!