IntlProvider中的属性变更,并不会触发FormattedMessage重新渲染
解决:在组件中加入key
大型项目不建议使用这种方案,因为:会引起此<IntlProvider>
包裹下的所有组件全部被更新
import { FormattedMessage } from 'react-intl';
<FormattedMessage id="common.search" defaultMessage="查询" />
<FormattedMessage id="common.reset" defaultMessage="重置" />
<FormattedMessage id="common.title" defaultMessage="页面标题" />
<Modal
title={<FormattedMessage id="common.add" defaultMessage="新增" />}
visible={visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<Form onSubmit={this.handleSubmit}>
<Item
{...attrs} // 展开多属性
label={<FormattedMessage id="common.department" defaultMessage="部门" />}
/>
</Form>
var defaultProps = {
formats: {},
messages: {},
textComponent: 'span',
defaultLocale: 'en',
defaultFormats: {}
};
FormattedMessage常用的属性
- id 文件中的属性名,唯一的,重复报错
- defaultMessage 中的name和values中的key对应,动态传递参数
- 当在locale配置文件中,没有找到这个id的时候,输出的结果就是 defaultMessage的值
- tagName 设置生成html标签
- description 这个位置替代的字符串的描述,便于维护代码
```jsx
<a name="g8bG7"></a>
## FormattedMessage细节
1. FormattedMessage 用于组件的渲染场景,并不适合用于占位符,替换文本等
2. placeholder 不能使用 FormattedMessage,实际占位符中返回[Object object],
1. 因为:FormattedMessage是个组件,对象类型,placeholder接收的 String类型
1. FormattedMessage 默认生成一个 span,不是纯文本字符串;默认返回 <span>标签
2. 解决:用 injectIntl 将 intl注入到组件
<a name="o0hOg"></a>
### tabList
```jsx
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
const tabList = [
{
key: 'title',
tab: <FormattedMessage id="table.tab1" defaultMessage="名称" />,
},
{
key: 'phone',
tab: <FormattedMessage id="table.tab2" defaultMessage="电话" />,
},
];
injectIntl处理字符串
import {injectIntl, defineMessages} from 'react-intl';
import {connect} from 'react-redux';
import PageTitle from './PageTitle';
const lang = defineMessages({
label: {id: "common.home.title", defaultMessage: "首页"},
});
function mapStateToProps(state, props) {
const { intl } = props
return {
label: intl.formatMessage(lang.label),
}
}
export default injectIntl(connect(mapStateToProps)(MyComponent))
import React from 'react';
import { injectIntl, intlShape, FormattedRelative } from 'react-intl';
Parent.propTypes = {
intl: intlShape.isRequired
}
function Parent(props) {
const { intl: {formatMessage} } = props
const placeholder = formatMessage({id: 'messageId'});
// 动态传值 第一个参数 id;第二个参数 value
const name = formatMessage({id: 'intl.name'},{name: 'lucy'})
return(
<div>
<input placeholder={placeholder} />
<p title={intl.formatDate(date)}>
<FormattedRelative value={date}/>
</p>
<FormattedMessage
id="intl.name"
values={{name: <b>{name}</b>}}
/>
</div>
);
}
export default injectIntl(Parent);
class组件
injectIntl(Component);
this.props.intl.formatMessage(...)
@injectIntl
class Parent extends Component {
render() {
const {intl} = this.props
const defineMessage = defineMessages({
batchPlaceholder: {
id: 'list.placeholder',
defaultMessage: '请选择用户'
}
})
return (
<div>{intl.formatMessage(defineMessage.batchPlaceholder)}</div>
)
}
}
defineMessages 定义key值
优点:自动的多语言提取
缺点:
- 组件多语言方便
- 字符串多语言每次都要注入 intl;原因?formatMessage react-i18n不直接暴露 ```jsx import { injectIntl, defineMessages } from ‘react-intl’;
@injectIntl const defineMessage = defineMessages({ placeholder: { id: ‘member.info.placeholder’, defaultMessage: ‘请选择’ } })
intl.formatMessage(defineMessage.placeholder)
<a name="QJkvX"></a>
## 动态传值
locales/
```jsx
// en-US.json
const en_US = {
hello: "Hello, {name}!"
}
// zh-CN.json
const zh_CN = {
hello: "{name},你好!"
}
defineMessage.json定义常量
- 定义常量 utils/defineMessage.js
- 在组件引入常量使用
defineMessage.js
import { defineMessages } from 'react-intl';
const RuleMessage = defineMessages({
rule: {
id: 'common.rule',
defaultMessage: '第{number}条规则',
},
title: {
id: 'login.title',
defaultMessage: '管理员登录'
},
placeholder: {
id: 'common.placeholder',
defaultMessage: '请输入 {value}',
},
help: {
id: 'common.help',
defaultMessage: '需要帮助'
}
}
Component组件使用
import { injectIntl } from 'react-intl';
import { defineMessage as lang } from '$utils/defineMessage';
// hooks
function App({intl}) {
const { formatMessage } = intl;
const {
name: formatMessage(lang.rule, { number }),
user: 'lucy',
}
}
// class组件
@injectIntl
class Login extends React.PureComponent {
render () {
const { intl: formatMessage } = this.props;
return (
<Card title={forMatMessage(lang.title)} />
)
}
}
export default Login
FormattedMessage 传值
import { FormattedMessage } from 'react-intl';
<FormattedMessage
id="intl.name"
tagName="div"
description="用户名"
defaultMessage="Hello, {name}!"
values={{name: <b>{name}</b>}}
/>