记一次大型React项目的国际化方案探索

栏目: IOS · Android · 发布时间: 6年前

内容简介:提起React项目国际化,首先想到著名的由于项目使用redux来管理状态,将语言环境与翻译文本都放入reducer中,使用相关action来触发语言切换:完成之后发现初始化的时候可以访问到store,使用指定的默认语言环境,但切换语言无效,排查后发现触发action后reducer确实更改了,但没有触发组件更新。查阅相关文档后,使用react内部的key属性来强制触发更新:
  • 项目:大型数据管理系统,涉及硬件设备数据监控、日常业务信息管理等
  • 技术:前后端分离,前端主要基于React-Redux
  • 需求:前端一键无缝切换多国语言

使用 react-intl

提起React项目国际化,首先想到著名的 react-intl 库,这个库提供了针对组件、日期、数字、字符串等多种国际化方法。使用方法也很简单:

  1. 将不同语言的翻译文件放在各自的js文件中,同一处文本的多种语言翻译使用相同的key

    // en_US.js
    const en_US = {
        "intl_hello": "Hello!",
    }
    export default en_US;
    
    // zh_CN.js
    const zh_CN = {
        "intl_hello": "你好!",
    }
    export default zh_CN;
    复制代码
  2. 在入口文件中配置 react-intl 库

    // index.js
    import { addLocaleData, IntlProvider } from 'react-intl';
    // 引入多语言环境
    import en from 'react-intl/locale-data/en';
    import zh from 'react-intl/locale-data/zh';
    addLocaleData([...en, ...zh]); 
    // 引入翻译文本
    import en_US from '.../intl/en_US.js';
    import zh_CN from '.../intl/zh_CN.js';
    const messagesMap = {
        en: en_US,
        zh: zh_CN
    }
    const locale = 'zh'; // 此处做了简化,下文将从redux中获取语言环境
    render((
    	// 使用<IntlProvicer>包装项目组件,配置语言环境和翻译文本
        <IntlProvider locale={local} messages={messages[local]}>
            //···
        </IntlProvider>
    ), document.getElementById("root"));
    复制代码
  3. 使用 react-intl 中内置的组件或方法替换需要做多语言的字符串、时间等,具体可参考 API文档

react-intl与redux

由于项目使用redux来管理状态,将语言环境与翻译文本都放入reducer中,使用相关action来触发语言切换:

// actions.js
export const switchLocal = local => ({
    type: 'SWITCH_INTL_LOCAL',
    payload: { local },
});

// reducers.js
import en_US from '.../intl/en_US.js';
import zh_CN from '.../intl/zh_CN.js';
const messagesMap = {
    en: en_US,
    zh: zh_CN
}
const defaultLocal = { //默认语言环境,也可从浏览器或用户配置数据中获取
    local: 'zh',
    messages: messagesMap.zh
};
export const intlLocal = (state=defaultLocal, action) => {
    switch(action.type) {
        case 'SWITCH_INTL_LOCAL':
            return {
                local: action.payload.local,
                messages: messagesMap[action.payload.local],
            }
        default:
            return state;
    }
}

// index.js
// 略去了文件中的redux配置等代码
const { local, messages } = store.getState().intlLocal; // 从store中获取语言配置
render((
	// react-redux中的Provider需要包在IntlProvider之外,IntlProvider才能访问到store
    <Provider store={store}>
        <IntlProvider locale={local} messages={messages}>
            //···
        </IntlProvider>
	</Provider>
), document.getElementById("root"));
复制代码

完成之后发现初始化的时候可以访问到store,使用指定的默认语言环境,但切换语言无效,排查后发现触发action后reducer确实更改了,但没有触发组件更新。查阅相关文档后,使用react内部的key属性来强制触发更新:

// index.js
render((
    <Provider store={store}>
       // 加入key属性来强制触发更新
        <IntlProvider key={local} locale={local} messages={messages}>
            //···
        </IntlProvider>
	</Provider>
), document.getElementById("root"));
复制代码

存在问题与方案探讨

在上一步中使用key来强制触发更新,对于一般简单的网站或前端系统来说,到这一步就可以了。

万恶的但是,由于接手的系统过于复杂,使用key强制触发组件更新时,会引起此 <IntlProvider> 包裹下的所有组件全部被更新,导致类似于页面整体被刷新的效果,从而出现websocket重连、数据丢失等一系列问题,由于不便于动用其他模块,思考过后剩下两种方案:

  1. 语言切换时给予相应提示,然后跳转到欢迎界面,这样重新进入各子系统时会重新发起各种连接。由于并不会经常切换语言,而且语言切换一般也就是发生在刚进入系统的时候,所以这个方案是最实用也最省力的。又是万恶的但是,由于项目背景比较复杂,上面领导的意思是像那些大型网站一样“无缝”切换中英文,一跳转就“有缝”了。。根本不考虑一个网站和一个大型B/S系统的差异,于是在需求降级可能性微乎其微的条件下,这个最合适的方案也只能作为紧急备用方案了。
  2. 修改 react-intl 库,需要包装库中用到的每个方法,将数据源由Context改为redux的store。做的时候发现基本只是在处理字符串,就干脆去掉了 react-intl 库的依赖,手写了个类似于intl库中的 <FormattedMessage> 组件,使用的时候又发现只能用于组件的局限性,又参考阿里的 react-intl-universal ,写了个直接由key生成翻译文本的方法。而这个方案目前还在完善和测试中。

以上所述就是小编给大家介绍的《记一次大型React项目的国际化方案探索》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Artificial Intelligence

Artificial Intelligence

Stuart Russell、Peter Norvig / Pearson / 2009-12-11 / USD 195.00

The long-anticipated revision of this #1 selling book offers the most comprehensive, state of the art introduction to the theory and practice of artificial intelligence for modern applications. Intell......一起来看看 《Artificial Intelligence》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

html转js在线工具
html转js在线工具

html转js在线工具