使用 react-intl 串国际化有两种情况:组件和字符串。绝大部分情况都可以使用组件的方式传入ID属性就可以解决需求问题,但遇到无法使用JSX的时候,就只能使用字符串的方式国际化了。
1、组件国际化
主要使用FormattedMessage, injectIntl
两个API
1. 封装组件
// IntlMessages.js
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
const InjectMassage = props => <FormattedMessage {...props} />;
export default injectIntl(InjectMassage, {
withRef: false,
});
2. 使用
import React from 'react';
...
<Tooltip title={<IntlMessages id={item.id} />} placement="right" />
2、字符串国际化
这种需求最常见的应该就是input输入框的placeHolder属性无法使用jsx的时候了
这种不需要额外封装组件,直接使用injectIntl
包裹当前组件就可以了。
// AutocompleteComponent.js
import React, { useState, useMemo, useRef } from 'react';
import { injectIntl } from 'react-intl';
import Autocomplete from '@material-ui/lab/Autocomplete';
const AutocompleteComponent = props => {
console.log(props);
const {
intl, // 通过react-intl的高阶函数injectIntl包裹当前组件获取 - 字符串国际化
intlId,// 国际化对应的id
...
} = props;
return (
<Autocomplete
multiple
freeSolo
options={[]}
{...props}
onChange={change}
renderInput={params => (
<TextField
className={classes.autoInput}
{...params}
{...inputProps}
error={isError}
placeholder={intl.formatMessage({ id: intlId })}
onChange={null}
onMouseOver={() => setInputStatus('HOVER')}
onMouseLeave={() => setInputStatus('LEAVE')}
onFocus={() => setFocus(true)}
onBlur={() => setFocus(false)}
/>
)}
/>
);
}
export default injectIntl(AutocompleteComponent);
总结
1、组件国际化使用组件 IntlMessages
2、字符串国际化:
1. 使用 injectIntl
包裹当前组件,如injectIntl(Input)
2. 通过 props 获取 injectIntl传递的intl
属性
3. 使用 intl.formatMessage({ id: intlId })
实现国际化
PS:如果使用了memo等性能优化逻辑,要注意国际化切换的时候也能实时触发intl.formatMessage({ id: intlId })
如:
/**
* 动态计算 placeholder 的展示
*/
const memoHolder = useMemo(() => {
const arr = [...filterParams];
arr.splice(0, values.length);
return getPlaceHolder(arr, intl);
// 这里使用了缓存函数usememo,所以切换国际化的时候需要加入 locale 同步触发更新
}, [values, filterParams, locale]);