使用 React 上下文进行国际化
Using React Context for Internationalization
我通过大量研究得知 internationalization/localization 是 React 的 context 功能的少数合法用例之一。但是,我的问题是关于是否真的需要 使用上下文。将要国际化的组件包装在提供本地化字符串作为 prop 的高阶组件中是否同样有效?例如对于支持英语和西班牙语的应用:
// 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 注入每个需要其中一个字符串的组件的开销。是否有任何其他原因不推荐此解决方案?
使用大型本地化结构作为 Component
的 props
之一不会造成惩罚。因为对象不是按值传递的,而是复制对对象的引用。所以没有什么需要担心的问题。
真正的问题是,当您不使用 context
时,您必须将本地化从根 Component
一路传递到最底层。如果您的中级 Components
不关心本地化,他们仍然必须接受本地化道具并进一步传递它们。
这就是为什么人们使用 context
: 来让中级 Components
完全不知道 Components
使用的一些在层次结构中较低的东西。
UPDATE. 您使用 WithLocale
的解决方案将起作用,尽管在切换语言环境时强制 Components
重绘存在问题。您必须在两个地方更新 currentLocale
:WithLocale.js
内部和您的根目录 Component
。除此之外,与使用 context
相比,我没有看到任何可能的缺点。
我通过大量研究得知 internationalization/localization 是 React 的 context 功能的少数合法用例之一。但是,我的问题是关于是否真的需要 使用上下文。将要国际化的组件包装在提供本地化字符串作为 prop 的高阶组件中是否同样有效?例如对于支持英语和西班牙语的应用:
// 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 注入每个需要其中一个字符串的组件的开销。是否有任何其他原因不推荐此解决方案?
使用大型本地化结构作为 Component
的 props
之一不会造成惩罚。因为对象不是按值传递的,而是复制对对象的引用。所以没有什么需要担心的问题。
真正的问题是,当您不使用 context
时,您必须将本地化从根 Component
一路传递到最底层。如果您的中级 Components
不关心本地化,他们仍然必须接受本地化道具并进一步传递它们。
这就是为什么人们使用 context
: 来让中级 Components
完全不知道 Components
使用的一些在层次结构中较低的东西。
UPDATE. 您使用 WithLocale
的解决方案将起作用,尽管在切换语言环境时强制 Components
重绘存在问题。您必须在两个地方更新 currentLocale
:WithLocale.js
内部和您的根目录 Component
。除此之外,与使用 context
相比,我没有看到任何可能的缺点。