组件之路---国际化

2018-01-24  本文已影响0人  hsay

虽然本文的题目叫“组件之路---国际化”,但是本文并不是讲国际化方案的,本文的重点是基于antd国际化组件的实现,去分析一类问题的解决思路。


LocaleProvider国际化

antd实现国际化的组件是LocaleProvider,即将需要国际化的组件作为LocaleProvider的子组件使用:

<LocaleProvider>
    <A   />
    <B   />
<LocaleProvider>

这里组件A与组件B是在需要的时候进行国际化转换的组件。

这里考虑LocaleProvider与A B组件该如何实现呢?
首先看一个应用方面的需求,如下图所示:

Locale.gif

页面中罗列了若干种需要进行国际化的组件,我们选择在中英文两种语言下切换,所有的组件都需要完成更新。

设计思路

1:每个需要国际化的组件都应该有其自身的文案,该文案的组织应该与该组件在同一个目录下:

 ComponentA-|
              index.js
              Locale-|
                       zh_CN.js
                       zh_TW.js
                       en_US.js
                       ...
                       
ComponentB-|
              index.js
              Locale-|
                       zh_CN.js
                       zh_TW.js
                       en_US.js
                       ...
                      

2:将这些分散的组件文案统一管理。

//index.js

var zh_CN1 = require("ComponentA/Locale/zh_CN");
var zh_CN2 = require("ComponentB/Locale/zh_CN");

export default  {
    ComponentA:zh_CN1,
    ComponentB:zh_CN2,
}

3:容器组件统一在文案中获取数据

var zh_CN = require("./index");

再根据需求将其传给不同的组件

<A  locale={zh_CN['ComponentA']} />
<B  locale={zh_CN['ComponentB']} />

在逻辑和功能上以上步骤是没有问题的,但是这里我们需要考虑一点就是通过这种参数传递的方式,最好的情况是组件A B就是需要国际化的组件,但是如果需要组件化的组件嵌套在其他组件之内呢?是否需要将参数层层传递呢?

这其实是一个很常见的问题,react中有context的概念可以帮助我们解决这个问题,antd的LocaleProvider其实就是基于context提供文案信息的。

基于context的实现

LocaleProvider作为容器组件,为其他所有子组件提供统一的数据,LocaleProvider需定义childContextTypes以及getChildContext。

  static childContextTypes = {
    antLocale: PropTypes.object,
  };

  getChildContext() {
    return {
      antLocale: {
        ...this.props.locale,
        exist: true,
      },
    };
  }

需要国际化的子组件定义contextTypes,然后通过this.context在组件内部使用传入的文案信息。

  static contextTypes = {
    antLocale: PropTypes.object,
  };
  const { antLocale } = this.context;

总结

react 中虽然提供了context这样的方式,但是官方并不推荐直接使用,除非你很清楚的知道你在干什么的情况下。如果你的应用中出现了若干只能通过变量提升或者context的方式传递数据才能解决问题的话,你就需要考虑是否需要引入数据流管理工具了。

上一篇 下一篇

猜你喜欢

热点阅读