内容简介:这里想和大家交流的并不是如何使用
react 的国际化方案,可以说是十分成熟了。
react-intl 一用上,文本,日期、货币统统搞定。
这里想和大家交流的并不是如何使用 react-intl ,抑或如何在 redux 框架中去使用。
而是一个小知识,如何在 placeholder 等属性中支持多语言,并且你只需按照 react-intl 的方式去维护多套语言库。
因为像 placeholder , title 这种 HTML 自带的属性,组件库向来都是直接支持的,那么问题来了,使用 react-intl 中的 <FormattedMessage /> 作为一个 Object 是无法用到这些属性中去的,那么我们应该怎么去处理这个问题呢?
他山之石,可以攻玉
下面先说几个我搜索到的方法。
injectIntl() <FormattedMessage />
以上两种方法都可以在这个 issue 中找到。
两种方式的实现原理很清晰。
方法一,强调使用高阶组件来处理这个问题,将 intl 注入到组件的 props 中,最后使用 intl.formatMessage 来解决问题。
方法二,很巧妙的利用到了 <FormattedMessage /> 组件的返回值,函数式的渲染了自身的子组件。
这两种思路固然都有可取之处,但是也有相应的问题。
方法一: injectIntl()
如果没有从全局层面出发,去封装的这种只是用于渲染的高阶组件,带来的成本,可想而知。
举个例子,我们有时候会封装一些自己的基础业务组件 BaseApp ,他们本身并没有render方法,在不同权限的客户访问时,实现不同的派生类( StaffApp , CustomerApp ),对基础业务组件进行调用。
class BaseApp extends Component {
renderPersonInfo() {}
renderDataAnalytical() {}
renderTasks() {}
}
class StaffApp extends BaseApp {
render() {
return (
{
this.renderPersonInfo(),
this.renderDataAnalytical()
}
)
}
}
class CustomerApp extends BaseApp {
render() {
return (
{
this.renderPersonInfo(),
this.renderTasks()
}
)
}
}
复制代码
假设这个时候我们对 BaseApp 进行 injectIntl ,那么原本可以继承的方法,就全部失效了。所以我们必须对派生类进行 injectIntl , 相当于,本来要做一次的事情,做了 N 次。
当然,我们可以把 BaseApp 中用到 placeholder 的组件,单独的抽出来,进行 injectIntl ,不失为一种解决方案。
所以虽然 injectIntl 是把好刀,但是用得好,用不好,就要看自己对整个项目的理解了。
方法二:组件返回值
抛开这么写,到底是否优美不谈。
最大的问题,还是带来了不必要的 dom 结构,因为 <FormattedMessage /> 组件是会渲染 <span /> 标签的。
想象下你的 input 组件外面还包了一个 span 是不是瑟瑟发抖呢。
用自己的思路,试试看
基于上述情况,我认为以上两种方法,不太适合目前的项目,那就是要自己造轮子啦。
开心,又可以自己造轮子啦。
先亮代码
const intl = {
lang: {}
};
intl.formatMessage = (props) => {
let message = intl.lang[props.id] || props.defaultMessage || props.id;
if (!props.values) return message;
const keys = Object.keys(props.values);
for (let i = 0, l = keys.length; i < l; i++) {
const key = keys[i];
message = message.replace(new RegExp(`{${key}}`, "g"), props.values[key]);
}
return message;
}
export default intl;
复制代码
原理比较简单,两步。
程序初始化的时候,对 intl.lang 赋值,同 react-intl 。
利用 props 中的 id 和 values 属性,获取值并进行替换,返回真正的值。
使用方法:
<Input
value={showName}
// placeholder="支持(1-10)位中文、英文与数字"
placeholder={intl.formatMessage({id: "intl.showName.placeholder"})}
onChange={this.handleNameChange.bind(this)}
/>
复制代码
以上所述就是小编给大家介绍的《React小知识(3) - 国际化中碰到的问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 当 Structured Streaming 碰到 Kafka
- 「学习笔记」无法远程访问 MySQL 碰到的坑
- Junit单元测试碰到静态变量如何处理
- Flutter实现国际化
- Webnovel 国际化实践
- 聊聊国际化MessageSource
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Mobilizing Web Sites
Layon, Kristofer / 2011-12 / 266.00元
Everyone has been talking about the mobile web in recent years, and more of us are browsing the web on smartphones and similar devices than ever before. But most of what we are viewing has not yet bee......一起来看看 《Mobilizing Web Sites》 这本书的介绍吧!