React-Intl,实现React项目的前端国际化

成都创新互联公司是一家专注于网站设计、成都网站制作与策划设计,原阳网站建设哪家好?成都创新互联公司做网站,专注于网站建设十年,网设计领域的专业建站公司;建站业务涵盖:原阳等地区。原阳做网站价格咨询:18982081108

本文讲解如何使用 React-Intl 库给你的 React 应用做国际化。

安装

React 项目默认你已经搭建好了。可以用过气的 CRA,流行的 vite,或者用 React 推荐的 Next.js。

安装 React-Intl。

npm i -S react-intl

或者用 yarn。

yarn add react-intl

使用

接着我们需要将国际化能力注入到 React 应用中。

使用的是经典的 context 上下文方案:

const root = ReactDOM.createRoot(
document.getElementById('root')
);

root.render(



);

IntlProvider 是一个 context.provider 组件,用来注入一些国际化需要的信息。其中最重要的信息是 locale 和 messages。

locale 是一个字符串,代表一个语言标识,使用了 BCP 47 语言标记规范。比如中文用 ​​zh​​​,英文用 ​​en​​​,简体用 ​​zh-CN​​。

标识符是会提供给浏览器自带的 Intl 对象使用的,Intl 对象的方法会通过它确定如何做转换,比如不同国家数字的分隔符是不同的。

可以看到,原点、逗号、空格,什么都有。所以你要传一个正确的语言标识符。

messages 就简单多了,就是一个 id 到 value 的映射,组件中传一个 id,就能拿到对应的语言文案了。比如

const zh = {
'command.undo': '撤销',
'command.redo': '重做',
'arrange.forward': '上移一层',
'arrange.backward': '下移一层',
'arrange.front': '移到顶部',
'arrange.back': '移到底部',
'zoom.zoomIn': '放大',
'zoom.zoomOut': '缩小'
};

const en = {
'command.undo': 'Undo',
'command.redo': 'Redo',
'arrange.forward': 'Forward',
'arrange.backward': 'Backward',
'arrange.front': 'Bring to Front',
'arrange.back': 'Send to Back',
'zoom.zoomIn': 'Zoom In',
'zoom.zoomOut': 'zoom Out',
};

更具体的引入写法:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { IntlProvider } from 'react-intl';
import { zh } from './locale/zh';
import { en } from './locale/en';

const messageMap = {
zh,
en,
};

const getLocale = () => {
const locale = navigator.language;
return locale.startsWith('zh') ? 'zh' : 'en'; // en 是兜底语言
};
const locale = getLocale();

const root = ReactDOM.createRoot(
document.getElementById('root')
);
root.render(



);

  1. 计算一个语言标识符,因为网站支持的语言可能就两三种,当用户客户端的语言不在范围内时,给一个兜底的。
  2. 确认语言后,找出对应的 messages 对象。

然后是一些其他的点:如果语言很多,可以考虑做语言包懒加载。另外还要做用户修改语言后,更新 locale 和 messages props。

组件

然后是在业务组件中使用国际化文案。

最常用的就是 FormattedMessage 组件了,给 id props 提供 id 即可。

如果你需要得到文案字符串,传入到一些组件中,比如 tooltip,你可以用主流的 hook 写法:

import { useIntl } from 'react-intl';

const intl = useIntl();

或者可以用 HOC(高阶组件),我没用过,我不写类组件。

类型安全

如果你用 TypeScript,你会希望传入的 id 是有类型的,反正写错 id。React-Intl 提供了全局类型的设置。你只需要这样写:

import { en } from './locale/en';
import { zh } from './locale/zh';


declare global {
namespace FormatjsIntl {
interface Message {
ids: (keyof typeof zh) & (keyof typeof en)
}
}
}

keyof typeof zh 就是将中文 message 对象的 key 提取为一个联合类型。

这里我巧妙地用了一个 & 交叉类型,这样不在二者 id 的交集内的 key 会被排除在外,防止使用一个没有在所有语言中都被定义的 id。

locale 也可以设置类型,防止错误设置一些不支持的语言标识。如下:

declare global {
namespace FormatjsIntl {
interface IntlConfig {
locale: 'en' | 'zh'
}
}
}

可能你希望 en 和 zh 的 key 要一致,我这里想到一个比较巧妙的做法。en 作为兜底语言,用 typeof 拿到类型,作为其他语言的类型,防止 id 漏写。

const en = {
'delete': 'Delete',
}

// zh 对象的类型是 typeof en
const zh: (typeof en) = {
'delete': '删除',
}

message 不支持嵌套

React-Intl 的 message 是不支持嵌套的。

你可以这样写:

const zh = {
'command.undo': '撤销',
'command.redo': '重做',
}

但不能这样写:

const zh = {
'command': {
'undo': '撤销',
'redo': '重做',
}
}

这个我是支持的。

嵌套并无必要,我们加前缀就好了,并且方便全局搜索,能够快速定义一个国际化 id 的文本位置。类似 Vue 框架会做大量的驼峰和连线符的变换,全局搜索非常不友好,我不喜欢。

如果你喜欢嵌套的风格,可以考虑写一些脚本,支持将嵌套的转换为拍平格式。

结尾

以上是 React-Intl 的一些入门用法。

分享名称:React-Intl,实现React项目的前端国际化
网站链接:http://www.shufengxianlan.com/qtweb/news29/483279.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联