使用React Context进行国际化

时间:2017-08-28 04:39:49

标签: reactjs internationalization higher-order-components

我从相当多的研究中了解到,国际化/本地化是React context功能的少数合法用例之一。但是我的问题是关于是否真的需要来使用上下文。将组件国际化包装在一个提供本地化字符串作为道具的高阶组件中是不是也可行?例如对于支持英语和西班牙语的应用程序:

// WithLocale.js
import React from 'react';

import en from './locales/en-US.json';
import es from './locales/es-ES.json';

const locales = {'en-US': en, 'es-ES': es};

let currentLocale = (navigator.languages && navigator.languages[0])
    || navigator.language
    || navigator.userLanguage
    || 'en-US';

const WithLocale = (WrappedComponent) => {
    return (props) => {
            const locale = { strings: locales[currentLocale] };
            return <WrappedComponent {...props} locale={locale} />
    }
};

export default WithLocale;

使用本地化JSON,例如:

// en.json
{
  "header": "My App",
  "description": "This is an internationalizated app in React",
}

这是一个如何在组件中使用的基本示例:

import React from 'react';
import PropTypes from 'prop-types';
import WithLocale from './WithLocale';

const SubComponent = (props) => (
        <div>
            <p className="App-intro">
                {props.locale.strings.description}
            </p>
        </div>
);

SubComponent.propTypes = {
    locale: PropTypes.object
};

export default WithLocale(SubComponent);

我能想到的主要问题是在每个需要其中一个字符串的组件中注入一个可能很大的JSON的开销。是否还有其他原因使此解决方案不受欢迎?

1 个答案:

答案 0 :(得分:1)

使用大型本地化结构作为props的{​​{1}}之一,不会造成任何惩罚。因为对象不是通过值传递的,所以正在复制对象的引用。所以没有一个问题值得关注。

真正的问题是,当您不使用Component时,您必须将本地化从根context一直传递到最底层的Component。如果您的中间人Components不关心本地化,他们仍然必须接受本地化道具并将其进一步传递。

这就是为什么人们使用context:让中间Components完全不知道层次结构较低的Components使用的某些东西。

更新。使用WithLocale的解决方案可行,但在切换区域设置时强制Components重绘时会出现问题。您必须在两个位置更新currentLocale:在WithLocale.js内和您的根Component。除此之外,与使用context相比,我没有看到任何可能的缺点。