I18n与React和i18next
越来越多的应用程序正在为全球市场设计,这意味着您的应用程序需要为使用各种语言和方言的受众工作。 React 没有内置国际化 (i18n),但国际化应用程序并不难,尤其是在 i18next 的帮助下。
i18next 是一个用 JavaScript 编写的 i18n 框架。 它提供了标准的 i18n 插值、格式化和处理复数和上下文功能。
一个 30,000 英尺的 i18next 视图将是它提供了一个函数,该函数接受一个键、一些选项并返回当前语言的值。
以下是使用上述功能的简单示例,只需一个简单的按键,没有任何选项。
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 已经为我们处理了这个问题,它将当前语言设置为英语,并将两种语言(英语和西班牙语)的翻译硬编码。 有关更多选项,请参阅 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
手动集成从导入我们预配置的 i18next 实例开始,该实例将提供 t
功能。
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> ) } }
请参阅上述代码的 工作示例 。
虽然我们修复了语言更改后组件不重新渲染的问题,但我们引入了很多样板代码:
- 添加了两个生命周期方法(componentDidMount 和 componentWillUnmount)。 (这意味着我们必须从功能组件切换到类组件。)
- 添加了一个事件监听器,因此我们可以通知 React 语言已更改。
- 引入了一种机制来导致组件重新渲染。 在上面的示例中,正在使用状态。 另一种选择是在语言更改后调用 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 以获取有关配置、更高级翻译和其他绑定选项的更多详细信息。