内容简介:这里想和大家交流的并不是如何使用
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
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。